use tracing::warn;
use super::*;
#[instrument(skip_all)]
pub(crate) fn format_args(parent: &LinkedNode, children: &[String], ctx: &mut Ctx) -> String {
if children.iter().any(|c| c.contains('\n')) {
return format_args_breaking(parent, children, ctx);
}
let mut res = format_args_one_line(parent, children, ctx);
let number_of_args = parent
.children()
.filter_map(|node| {
if [Comma, Space, LeftParen, RightParen].contains(&node.kind()) {
None
} else {
Some(node)
}
})
.count();
if number_of_args <= 1 {
return res;
}
if utils::max_line_length(&res) >= ctx.config.max_line_length {
debug!("format_args::breaking");
res = format_args_breaking(parent, children, ctx);
return res;
}
debug!("format_args::one_line");
res
}
pub(crate) fn format_args_one_line(
parent: &LinkedNode<'_>,
children: &[String],
ctx: &mut Ctx,
) -> String {
let mut res = String::new();
for (s, node) in children.iter().zip(parent.children()) {
match node.kind() {
Space => {}
Comma => {
if utils::next_is_ignoring(&node, RightParen, &[Space]) {
if node.parent_kind() == Some(Array) {
ctx.push_raw_in(",", &mut res)
}
} else {
ctx.push_raw_in(s, &mut res);
ctx.push_in(" ", &mut res);
}
}
_ => {
ctx.push_raw_in(s, &mut res);
}
}
}
res
}
pub(crate) fn format_args_breaking(
parent: &LinkedNode<'_>,
children: &[String],
ctx: &mut Ctx,
) -> String {
let mut res = String::new();
let mut missing_trailing = false;
for (s, node) in children.iter().zip(parent.children()) {
match node.kind() {
LeftParen => {
res.push_str(s);
res.push('\n');
res.push_str(&ctx.get_indent());
if let Some(next) = utils::get_next_ignoring(&node, &[Space]) {
if [LineComment, BlockComment].contains(&next.kind()) {
res.push_str(next.text());
res.push('\n');
res.push_str(&ctx.get_indent());
}
}
}
RightParen => {
res.push_str(s);
}
LineComment | BlockComment => {
}
Space => {}
Comma => {
let is_last_comma = utils::find_next(&node, &|x| x.kind() == Comma).is_none();
let is_trailing = utils::next_is_ignoring(&node, RightParen, &[Space]);
if is_last_comma && is_trailing {
assert!(s == ",");
ctx.push_raw_in(s, &mut res);
if utils::next_is_ignoring(&node, RightParen, &[Space]) {}
ctx.push_raw_in("\n", &mut res);
} else {
ctx.push_raw_in(&format!("{s}\n{}", ctx.get_indent()), &mut res);
if let Some(next) = utils::get_next_ignoring(&node, &[Space]) {
if [LineComment, BlockComment].contains(&next.kind()) {
res.push_str(next.text());
res.push('\n');
let is_trailing = utils::next_is_ignoring(&next, RightParen, &[Space]);
if !is_trailing {
res.push_str(&ctx.get_indent());
}
}
}
if is_last_comma && !is_trailing {
missing_trailing = true;
}
}
}
_ => {
ctx.push_raw_indent(s, &mut res);
let is_last = utils::next_is_ignoring(&node, RightParen, &[Space]);
if is_last && missing_trailing {
ctx.push_raw_in(",\n", &mut res)
}
}
}
}
res
}