-#[derive(new, Clone, Copy)]
-pub struct PairParts<'a> {
- prefix: &'a str,
- infix: &'a str,
- suffix: &'a str,
-}
-
-pub fn rewrite_pair<LHS, RHS>(
- lhs: &LHS,
- rhs: &RHS,
- pp: PairParts,
- context: &RewriteContext,
- shape: Shape,
- separator_place: SeparatorPlace,
-) -> Option<String>
-where
- LHS: Rewrite,
- RHS: Rewrite,
-{
- let lhs_overhead = match separator_place {
- SeparatorPlace::Back => shape.used_width() + pp.prefix.len() + pp.infix.trim_right().len(),
- SeparatorPlace::Front => shape.used_width(),
- };
- let lhs_shape = Shape {
- width: context.budget(lhs_overhead),
- ..shape
- };
- let lhs_result = lhs.rewrite(context, lhs_shape)
- .map(|lhs_str| format!("{}{}", pp.prefix, lhs_str))?;
-
- // Try to put both lhs and rhs on the same line.
- let rhs_orig_result = shape
- .offset_left(last_line_width(&lhs_result) + pp.infix.len())
- .and_then(|s| s.sub_width(pp.suffix.len()))
- .and_then(|rhs_shape| rhs.rewrite(context, rhs_shape));
- if let Some(ref rhs_result) = rhs_orig_result {
- // If the length of the lhs is equal to or shorter than the tab width or
- // the rhs looks like block expression, we put the rhs on the same
- // line with the lhs even if the rhs is multi-lined.
- let allow_same_line = lhs_result.len() <= context.config.tab_spaces()
- || rhs_result
- .lines()
- .next()
- .map(|first_line| first_line.ends_with('{'))
- .unwrap_or(false);
- if !rhs_result.contains('\n') || allow_same_line {
- let one_line_width = last_line_width(&lhs_result) + pp.infix.len()
- + first_line_width(rhs_result) + pp.suffix.len();
- if one_line_width <= shape.width {
- return Some(format!(
- "{}{}{}{}",
- lhs_result, pp.infix, rhs_result, pp.suffix
- ));
- }
- }
- }
-
- // We have to use multiple lines.
- // Re-evaluate the rhs because we have more space now:
- let mut rhs_shape = match context.config.indent_style() {
- IndentStyle::Visual => shape
- .sub_width(pp.suffix.len() + pp.prefix.len())?
- .visual_indent(pp.prefix.len()),
- IndentStyle::Block => {
- // Try to calculate the initial constraint on the right hand side.
- let rhs_overhead = shape.rhs_overhead(context.config);
- Shape::indented(shape.indent.block_indent(context.config), context.config)
- .sub_width(rhs_overhead)?
- }
- };
- let infix = match separator_place {
- SeparatorPlace::Back => pp.infix.trim_right(),
- SeparatorPlace::Front => pp.infix.trim_left(),
- };
- if separator_place == SeparatorPlace::Front {
- rhs_shape = rhs_shape.offset_left(infix.len())?;
- }
- let rhs_result = rhs.rewrite(context, rhs_shape)?;
- let indent_str = rhs_shape.indent.to_string_with_newline(context.config);
- let infix_with_sep = match separator_place {
- SeparatorPlace::Back => format!("{}{}", infix, indent_str),
- SeparatorPlace::Front => format!("{}{}", indent_str, infix),
- };
- Some(format!(
- "{}{}{}{}",
- lhs_result, infix_with_sep, rhs_result, pp.suffix
- ))
-}
-