use utils::{first_line_width, last_line_extendable, last_line_width, mk_sp,
trimmed_last_line_width, wrap_str};
+use std::borrow::Cow;
use std::cmp::min;
use std::iter;
+
use syntax::{ast, ptr};
use syntax::codemap::Span;
let connector = if fits_single_line && !parent_rewrite_contains_newline {
// Yay, we can put everything on one line.
- String::new()
+ Cow::from("")
} else {
// Use new lines.
if context.force_one_line_chain {
return None;
}
- format!("\n{}", nested_shape.indent.to_string(context.config))
+ nested_shape.indent.to_string_with_newline(context.config)
};
let first_connector = if is_small_parent || fits_single_line
{
""
} else {
- connector.as_str()
+ &connector
};
let result = if is_small_parent && rewrites.len() > 1 {
.width
.checked_sub(closer.len() + opener.len())
.unwrap_or(1);
- let indent_str = shape.indent.to_string(config);
+ let indent_str = shape.indent.to_string_with_newline(config);
let fmt_indent = shape.indent + (opener.len() - line_start.len());
let mut fmt = StringFormat {
opener: "",
let mut code_block_buffer = String::with_capacity(128);
let mut is_prev_line_multi_line = false;
let mut inside_code_block = false;
- let comment_line_separator = format!("\n{}{}", indent_str, line_start);
+ let comment_line_separator = format!("{}{}", indent_str, line_start);
let join_code_block_with_comment_line_separator = |s: &str| {
let mut result = String::with_capacity(s.len() + 128);
let mut iter = s.lines().peekable();
} else if is_prev_line_multi_line && !line.is_empty() {
result.push(' ')
} else if is_last && !closer.is_empty() && line.is_empty() {
- result.push('\n');
result.push_str(&indent_str);
} else {
result.push_str(&comment_line_separator);
let force_new_line_before_comment =
missing_snippet[..pos].contains('\n') || total_width > context.config.max_width();
let sep = if force_new_line_before_comment {
- format!("\n{}", shape.indent.to_string(context.config))
+ shape.indent.to_string_with_newline(context.config)
} else {
- String::from(" ")
+ Cow::from(" ")
};
Some(format!("{}{}", sep, missing_comment))
}
}
}
-impl RichChar for (char, usize) {
- fn get_char(&self) -> char {
- self.0
- }
-}
-
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
enum CharClassesStatus {
Normal,
rhs_shape = rhs_shape.offset_left(infix.len())?;
}
let rhs_result = rhs.rewrite(context, rhs_shape)?;
- let indent_str = rhs_shape.indent.to_string(context.config);
+ let indent_str = rhs_shape.indent.to_string_with_newline(context.config);
let infix_with_sep = match separator_place {
- SeparatorPlace::Back => format!("{}\n{}", infix, indent_str),
- SeparatorPlace::Front => format!("\n{}{}", indent_str, infix),
+ SeparatorPlace::Back => format!("{}{}", infix, indent_str),
+ SeparatorPlace::Front => format!("{}{}", indent_str, infix),
};
Some(format!(
"{}{}{}{}",
}
} else {
format!(
- "[\n{}{}\n{}]",
- nested_shape.indent.to_string(context.config),
+ "[{}{}{}]",
+ nested_shape.indent.to_string_with_newline(context.config),
list_str,
- shape.block().indent.to_string(context.config)
+ shape.block().indent.to_string_with_newline(context.config)
)
};
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
debug!("ControlFlow::rewrite {:?} {:?}", self, shape);
- let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
+ let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
let (cond_str, used_width) = self.rewrite_cond(context, shape, &alt_block_sep)?;
// If `used_width` is 0, it indicates that whole control flow is written in a single line.
if used_width == 0 {
fn extract_comment(span: Span, context: &RewriteContext, shape: Shape) -> Option<String> {
match rewrite_missing_comment(span, shape, context) {
Some(ref comment) if !comment.is_empty() => Some(format!(
- "\n{indent}{}\n{indent}",
+ "{indent}{}{indent}",
comment,
- indent = shape.indent.to_string(context.config)
+ indent = shape.indent.to_string_with_newline(context.config)
)),
_ => None,
}
IndentStyle::Block => cond_shape.offset_left(6)?,
};
let cond_str = cond.rewrite(context, cond_shape)?;
- let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
+ let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
let block_sep = match context.config.control_brace_style() {
ControlBraceStyle::AlwaysNextLine => &alt_block_sep,
_ if last_line_extendable(&cond_str) => " ",
};
let comma = arm_comma(context.config, body, is_last);
- let alt_block_sep = String::from("\n") + &shape.indent.to_string(context.config);
- let alt_block_sep = alt_block_sep.as_str();
+ let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
let combine_orig_body = |body_str: &str| {
let block_sep = match context.config.control_brace_style() {
let combine_next_line_body = |body_str: &str| {
if is_block {
return Some(format!(
- "{} =>\n{}{}",
+ "{} =>{}{}",
pats_str,
- next_line_indent.to_string(context.config),
+ next_line_indent.to_string_with_newline(context.config),
body_str
));
}
- let indent_str = shape.indent.to_string(context.config);
- let nested_indent_str = next_line_indent.to_string(context.config);
+ let indent_str = shape.indent.to_string_with_newline(context.config);
+ let nested_indent_str = next_line_indent.to_string_with_newline(context.config);
let (body_prefix, body_suffix) = if context.config.match_arm_blocks() {
let comma = if context.config.match_block_trailing_comma() {
","
} else {
""
};
- ("{", format!("\n{}}}{}", indent_str, comma))
+ ("{", format!("{}}}{}", indent_str, comma))
} else {
("", String::from(","))
};
let block_sep = match context.config.control_brace_style() {
- ControlBraceStyle::AlwaysNextLine => format!("{}{}\n", alt_block_sep, body_prefix),
- _ if body_prefix.is_empty() => "\n".to_owned(),
- _ if forbid_same_line => format!("{}{}\n", alt_block_sep, body_prefix),
- _ => format!(" {}\n", body_prefix),
+ ControlBraceStyle::AlwaysNextLine => format!("{}{}", alt_block_sep, body_prefix),
+ _ if body_prefix.is_empty() => "".to_owned(),
+ _ if forbid_same_line => format!("{}{}", alt_block_sep, body_prefix),
+ _ => format!(" {}", body_prefix),
} + &nested_indent_str;
Some(format!(
if let Some(cond_shape) = cond_shape {
if let Some(cond_str) = guard.rewrite(context, cond_shape) {
return Some(format!(
- "\n{}if {}",
- cond_shape.indent.to_string(context.config),
+ "{}if {}",
+ cond_shape.indent.to_string_with_newline(context.config),
cond_str
));
}
let nested_shape = shape
.block_indent(context.config.tab_spaces())
.with_max_width(context.config);
- let nested_indent_str = nested_shape.indent.to_string(context.config);
+ let nested_indent_str = nested_shape.indent.to_string_with_newline(context.config);
expr.rewrite(context, nested_shape)
- .map(|expr_rw| format!("\n{}{}", nested_indent_str, expr_rw))
+ .map(|expr_rw| format!("{}{}", nested_indent_str, expr_rw))
}
fn can_extend_match_arm_body(body: &ast::Expr) -> bool {
|| (context.inside_macro && !args_str.contains('\n')
&& args_str.len() + paren_overhead(context) <= shape.width) || is_extendable
{
+ let mut result = String::with_capacity(args_str.len() + 4);
if context.config.spaces_within_parens_and_brackets() && !args_str.is_empty() {
- format!("( {} )", args_str)
+ result.push_str("( ");
+ result.push_str(args_str);
+ result.push_str(" )");
} else {
- format!("({})", args_str)
+ result.push_str("(");
+ result.push_str(args_str);
+ result.push_str(")");
}
+ result
} else {
- format!(
- "(\n{}{}\n{})",
- nested_shape.indent.to_string(context.config),
- args_str,
- shape.block().indent.to_string(context.config)
- )
+ let nested_indent_str = nested_shape.indent.to_string_with_newline(context.config);
+ let indent_str = shape.block().indent.to_string_with_newline(context.config);
+ let mut result =
+ String::with_capacity(args_str.len() + 2 + indent_str.len() + nested_indent_str.len());
+ result.push_str("(");
+ result.push_str(&nested_indent_str);
+ result.push_str(args_str);
+ result.push_str(&indent_str);
+ result.push_str(")");
+ result
}
}
let new_index_rw = index.rewrite(context, index_shape);
match (orig_index_rw, new_index_rw) {
(_, Some(ref new_index_str)) if !new_index_str.contains('\n') => Some(format!(
- "{}\n{}{}{}{}",
+ "{}{}{}{}{}",
expr_str,
- indent.to_string(context.config),
+ indent.to_string_with_newline(context.config),
lbr,
new_index_str,
rbr
)),
(None, Some(ref new_index_str)) => Some(format!(
- "{}\n{}{}{}{}",
+ "{}{}{}{}{}",
expr_str,
- indent.to_string(context.config),
+ indent.to_string_with_newline(context.config),
lbr,
new_index_str,
rbr
|| fields_str.len() > one_line_width)
{
format!(
- "\n{}{}\n{}",
- nested_shape.indent.to_string(context.config),
+ "{}{}{}",
+ nested_shape.indent.to_string_with_newline(context.config),
fields_str,
- shape.indent.to_string(context.config)
+ shape.indent.to_string_with_newline(context.config)
)
} else {
// One liner or visual indent.
}
let mut attrs_str = field.attrs.rewrite(context, shape)?;
if !attrs_str.is_empty() {
- attrs_str.push_str(&format!("\n{}", shape.indent.to_string(context.config)));
+ attrs_str.push_str(&shape.indent.to_string_with_newline(context.config));
};
let name = field.ident.node.to_string();
if field.is_shorthand {
Shape::indented(shape.indent.block_indent(context.config), context.config)
.sub_width(shape.rhs_overhead(context.config))?;
let new_rhs = expr.rewrite(context, new_shape);
- let new_indent_str = &new_shape.indent.to_string(context.config);
+ let new_indent_str = &new_shape.indent.to_string_with_newline(context.config);
match (orig_rhs, new_rhs) {
(Some(ref orig_rhs), Some(ref new_rhs))
Some(format!(" {}", orig_rhs))
}
(Some(ref orig_rhs), Some(ref new_rhs)) if prefer_next_line(orig_rhs, new_rhs) => {
- Some(format!("\n{}{}", new_indent_str, new_rhs))
+ Some(format!("{}{}", new_indent_str, new_rhs))
}
- (None, Some(ref new_rhs)) => Some(format!("\n{}{}", new_indent_str, new_rhs)),
+ (None, Some(ref new_rhs)) => Some(format!("{}{}", new_indent_str, new_rhs)),
(None, None) => None,
(Some(ref orig_rhs), _) => Some(format!(" {}", orig_rhs)),
}
// start of the body, but we need more spans from the compiler to solve
// this.
if newline_brace {
- result.push('\n');
- result.push_str(&indent.to_string(self.config));
+ result.push_str(&indent.to_string_with_newline(self.config));
} else {
result.push(' ');
}
return None;
}
let mut result = String::with_capacity(1024);
- result.push('\n');
- let indentation = self.block_indent.to_string(self.config);
+ let indentation = self.block_indent.to_string_with_newline(self.config);
result.push_str(&indentation);
let itemize_list_with = |one_line_width: usize| {
if let ast::ItemKind::Impl(_, _, _, ref generics, _, ref self_ty, ref items) = item.node {
let mut result = String::with_capacity(128);
let ref_and_type = format_impl_ref_and_type(context, item, offset)?;
- let indent_str = offset.to_string(context.config);
- let sep = format!("\n{}", &indent_str);
+ let sep = offset.to_string_with_newline(context.config);
result.push_str(&ref_and_type);
let where_budget = if result.contains('\n') {
}
if !where_clause_str.is_empty() && !where_clause_str.contains('\n') {
- result.push('\n');
let width = offset.block_indent + context.config.tab_spaces() - 1;
let where_indent = Indent::new(0, width);
- result.push_str(&where_indent.to_string(context.config));
+ result.push_str(&where_indent.to_string_with_newline(context.config));
}
result.push_str(&where_clause_str);
visitor.format_missing(item.span.hi() - BytePos(1));
- let inner_indent_str = visitor.block_indent.to_string(context.config);
- let outer_indent_str = offset.block_only().to_string(context.config);
+ let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config);
+ let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
- result.push('\n');
result.push_str(&inner_indent_str);
result.push_str(visitor.buffer.to_string().trim());
- result.push('\n');
result.push_str(&outer_indent_str);
}
if offset.width() + last_line_width(&result) + trait_bound_str.len()
> context.config.comment_width()
{
- result.push('\n');
let trait_indent = offset.block_only().block_indent(context.config);
- result.push_str(&trait_indent.to_string(context.config));
+ result.push_str(&trait_indent.to_string_with_newline(context.config));
}
result.push_str(&trait_bound_str);
&& last_line_width(&result) + where_clause_str.len() + offset.width()
> context.config.comment_width()
{
- result.push('\n');
let width = offset.block_indent + context.config.tab_spaces() - 1;
let where_indent = Indent::new(0, width);
- result.push_str(&where_indent.to_string(context.config));
+ result.push_str(&where_indent.to_string_with_newline(context.config));
}
result.push_str(&where_clause_str);
match context.config.brace_style() {
_ if last_line_contains_single_line_comment(&result) => {
- result.push('\n');
- result.push_str(&offset.to_string(context.config));
+ result.push_str(&offset.to_string_with_newline(context.config));
}
BraceStyle::AlwaysNextLine => {
- result.push('\n');
- result.push_str(&offset.to_string(context.config));
+ result.push_str(&offset.to_string_with_newline(context.config));
}
BraceStyle::PreferSameLine => result.push(' '),
BraceStyle::SameLineWhere => {
if !where_clause_str.is_empty()
&& (!trait_items.is_empty() || result.contains('\n'))
{
- result.push('\n');
- result.push_str(&offset.to_string(context.config));
+ result.push_str(&offset.to_string_with_newline(context.config));
} else {
result.push(' ');
}
visitor.format_missing(item.span.hi() - BytePos(1));
- let inner_indent_str = visitor.block_indent.to_string(context.config);
- let outer_indent_str = offset.block_only().to_string(context.config);
+ let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config);
+ let outer_indent_str = offset.block_only().to_string_with_newline(context.config);
- result.push('\n');
result.push_str(&inner_indent_str);
result.push_str(visitor.buffer.to_string().trim());
- result.push('\n');
result.push_str(&outer_indent_str);
} else if result.contains('\n') {
result.push('\n');
if where_clause_str.is_empty() {
result.push_str(" =");
} else {
- result.push_str(&format!("\n{}=", indent.to_string(context.config)));
+ result.push_str(&format!(
+ "{}=",
+ indent.to_string_with_newline(context.config)
+ ));
}
// 1 = ";"
let nested_indent = offset.block_indent(context.config);
let nested_shape = Shape::indented(nested_indent, context.config);
let ty_str = static_parts.ty.rewrite(context, nested_shape)?;
- format!("\n{}{}", nested_indent.to_string(context.config), ty_str)
+ format!(
+ "{}{}",
+ nested_indent.to_string_with_newline(context.config),
+ ty_str
+ )
}
};
} else {
result.push_str("(");
if context.config.indent_style() == IndentStyle::Visual {
- result.push('\n');
- result.push_str(&arg_indent.to_string(context.config));
+ result.push_str(&arg_indent.to_string_with_newline(context.config));
}
}
} else {
let mut args_last_line_contains_comment = false;
if put_args_in_block {
arg_indent = indent.block_indent(context.config);
- result.push('\n');
- result.push_str(&arg_indent.to_string(context.config));
+ result.push_str(&arg_indent.to_string_with_newline(context.config));
result.push_str(&arg_str);
- result.push('\n');
- result.push_str(&indent.to_string(context.config));
+ result.push_str(&indent.to_string_with_newline(context.config));
result.push(')');
} else {
result.push_str(&arg_str);
.map_or(false, |last_line| last_line.contains("//"))
{
args_last_line_contains_comment = true;
- result.push('\n');
- result.push_str(&arg_indent.to_string(context.config));
+ result.push_str(&arg_indent.to_string_with_newline(context.config));
}
result.push(')');
}
arg_indent
};
- result.push('\n');
- result.push_str(&indent.to_string(context.config));
+ result.push_str(&indent.to_string_with_newline(context.config));
indent
} else {
result.push(' ');
rewrite_comments_before_after_where(context, span_before, span_after, shape)?;
let starting_newline = if where_clause_option.snuggle && comment_before.is_empty() {
- " ".to_owned()
+ Cow::from(" ")
} else {
- "\n".to_owned() + &block_shape.indent.to_string(context.config)
+ block_shape.indent.to_string_with_newline(context.config)
};
let clause_shape = block_shape.block_left(context.config.tab_spaces())?;
let comment_separator = |comment: &str, shape: Shape| {
if comment.is_empty() {
- String::new()
+ Cow::from("")
} else {
- format!("\n{}", shape.indent.to_string(context.config))
+ shape.indent.to_string_with_newline(context.config)
}
};
let newline_before_where = comment_separator(&comment_before, shape);
&& comment_after.is_empty() && !preds_str.contains('\n')
&& 6 + preds_str.len() <= shape.width || where_single_line
{
- String::from(" ")
+ Cow::from(" ")
} else {
- format!("\n{}", clause_shape.indent.to_string(context.config))
+ clause_shape.indent.to_string_with_newline(context.config)
};
Some(format!(
"{}{}{}where{}{}{}{}",
ty.rewrite(context, shape).map(|ty_str| {
// 1 = space between prefix and type.
let sep = if prefix.len() + ty_str.len() + 1 <= shape.width {
- String::from(" ")
+ Cow::from(" ")
} else {
let nested_indent = shape.indent.block_indent(context.config);
- format!("\n{}", nested_indent.to_string(context.config))
+ nested_indent.to_string_with_newline(context.config)
};
format!("{}{}{};", prefix, sep, ty_str)
})
Some(format!("{}{}{}; {}{}", macro_name, lbr, lhs, rhs, rbr))
} else {
Some(format!(
- "{}{}\n{}{};\n{}{}\n{}{}",
+ "{}{}{}{};{}{}{}{}",
macro_name,
lbr,
- nested_shape.indent.to_string(context.config),
+ nested_shape.indent.to_string_with_newline(context.config),
lhs,
- nested_shape.indent.to_string(context.config),
+ nested_shape.indent.to_string_with_newline(context.config),
rhs,
- shape.indent.to_string(context.config),
+ shape.indent.to_string_with_newline(context.config),
rbr
))
}
};
if multi_branch_style {
- result += " {\n";
- result += &arm_shape.indent.to_string(context.config);
+ result += " {";
+ result += &arm_shape.indent.to_string_with_newline(context.config);
}
result += write_list(&branch_items, &fmt)?.as_str();
if multi_branch_style {
- result += "\n";
- result += &indent.to_string(context.config);
+ result += &indent.to_string_with_newline(context.config);
result += "}";
}
let graphemes = UnicodeSegmentation::graphemes(&*stripped_str, false).collect::<Vec<&str>>();
let shape = fmt.shape;
- let indent = shape.indent.to_string(fmt.config);
+ let indent = shape.indent.to_string_with_newline(fmt.config);
let punctuation = ":,;.";
// `cur_start` is the position in `orig` of the start of the current line.
result.push_str(line);
result.push_str(fmt.line_end);
- result.push('\n');
result.push_str(&indent);
result.push_str(fmt.line_start);
let result = type_strs.join(joiner);
if result.contains('\n') || result.len() > shape.width {
let joiner_indent = shape.indent.block_indent(context.config);
- let joiner = format!("\n{}+ ", joiner_indent.to_string(context.config));
+ let joiner = format!("{}+ ", joiner_indent.to_string_with_newline(context.config));
type_strs.join(&joiner)
} else {
result
if is_internal {
match self.config.brace_style() {
BraceStyle::AlwaysNextLine => {
- let sep_str = format!("\n{}{{", self.block_indent.to_string(self.config));
- self.push_str(&sep_str);
+ let indent_str = self.block_indent.to_string_with_newline(self.config);
+ self.push_str(&indent_str);
+ self.push_str("{");
}
_ => self.push_str(" {"),
}