pub(crate) fn rule(
build_ctx: &crate::builder::BuildCtx,
node: &rnix::SyntaxNode,
) -> std::collections::LinkedList<crate::builder::Step> {
let mut steps = std::collections::LinkedList::new();
let mut children = crate::children::Children::new(build_ctx, node);
let vertical = children.has_comments()
|| children.has_newlines()
|| build_ctx.vertical;
let child = children.get_next().unwrap();
if vertical {
steps.push_back(crate::builder::Step::FormatWider(child));
} else {
steps.push_back(crate::builder::Step::Format(child));
}
if let rnix::SyntaxKind::TOKEN_COMMENT
| rnix::SyntaxKind::TOKEN_WHITESPACE =
children.peek_next().unwrap().kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
children.drain_trivia(|element| match element {
crate::children::Trivia::Comment(text) => {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::children::Trivia::Whitespace(_) => {}
});
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child));
let mut comment = false;
children.drain_trivia(|element| match element {
crate::children::Trivia::Comment(text) => {
comment = true;
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
}
crate::children::Trivia::Whitespace(_) => {}
});
let child = children.get_next().unwrap();
if vertical {
if comment
|| !matches!(
child.kind(),
rnix::SyntaxKind::NODE_ATTR_SET
| rnix::SyntaxKind::NODE_PAREN
| rnix::SyntaxKind::NODE_LAMBDA
| rnix::SyntaxKind::NODE_LET_IN
| rnix::SyntaxKind::NODE_LIST
| rnix::SyntaxKind::NODE_LITERAL
| rnix::SyntaxKind::NODE_STRING
)
{
let should_indent = !matches!(
child.kind(),
rnix::SyntaxKind::NODE_ATTR_SET
| rnix::SyntaxKind::NODE_PAREN
| rnix::SyntaxKind::NODE_LAMBDA
| rnix::SyntaxKind::NODE_LET_IN
| rnix::SyntaxKind::NODE_LIST
| rnix::SyntaxKind::NODE_STRING
) && build_ctx.indentation > 0;
if should_indent {
steps.push_back(crate::builder::Step::Indent);
}
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(child));
if should_indent {
steps.push_back(crate::builder::Step::Dedent);
}
} else {
steps.push_back(crate::builder::Step::Whitespace);
steps.push_back(crate::builder::Step::FormatWider(child));
}
} else {
steps.push_back(crate::builder::Step::Whitespace);
steps.push_back(crate::builder::Step::Format(child));
}
steps
}