1
Fork 0
mirror of https://github.com/RGBCube/alejandra synced 2025-07-29 19:47:45 +00:00

feat: formatter poc

This commit is contained in:
Kevin Amado 2022-01-09 22:15:38 -05:00
parent 6adfbe8516
commit 8d545a62ad
No known key found for this signature in database
GPG key ID: FFF341057F503148
77 changed files with 4210 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/result*
/target/
/tarpaulin*

16
Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[dependencies]
clap = "3"
rnix = "0.10"
rowan = "0.15"
walkdir = "2"
[dev-dependencies]
indoc = "*"
[package]
authors = ["Kevin Amado <kamadorueda@gmail.com>"]
description = "The uncompromising Nix formatter"
edition = "2021"
name = "alejandra"
repository = "https://github.com/kamadorueda/alejandra"
version = "0.1.0"

81
flake.nix Normal file
View file

@ -0,0 +1,81 @@
{
inputs =
{
flakeUtils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
};
outputs =
inputs:
inputs.flakeUtils.lib.eachDefaultSystem
(
system:
let
nixpkgs = import inputs.nixpkgs { inherit system; };
cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml);
in
{
checks =
{
defaultPackage = inputs.self.defaultPackage.${ system };
inherit (inputs.self.packages.${ system }) nixpkgsFormatted;
};
defaultApp =
{
type = "app";
program =
"${ inputs.self.defaultPackage.${ system } }/bin/alejandra";
};
defaultPackage =
nixpkgs.rustPlatform.buildRustPackage
{
pname = cargoToml.package.name;
version = cargoToml.package.version;
src = inputs.self.sourceInfo;
cargoLock.lockFile = ./Cargo.lock;
NIX_BUILD_CORES = 0;
meta =
{
description = inputs.self.description;
homepage = "https://github.com/kamadorueda/alejandra";
license = nixpkgs.lib.licenses.mit;
maintainers = [ nixpkgs.lib.maintainers.kamadorueda ];
};
};
devShell =
nixpkgs.mkShell
{
packages = [ nixpkgs.cargo-tarpaulin nixpkgs.rustup ];
shellHook =
''
rustup toolchain install nightly
'';
};
packages =
{
nixpkgsFormatted =
nixpkgs.stdenv.mkDerivation
{
name = "nixpkgs-formatted";
builder =
builtins.toFile
"builder.sh"
''
source $stdenv/setup
cp -rT $nixpkgs $out
chmod -R +w $out
alejandra $out
git diff --no-index $nixpkgs $out > $diff || true
'';
buildInputs =
[ inputs.self.defaultPackage.${ system } nixpkgs.git ];
nixpkgs = inputs.nixpkgs.sourceInfo.outPath;
NIX_BUILD_CORES = 0;
outputs = [ "diff" "out" ];
};
};
}
);
}

253
src/builder.rs Normal file
View file

@ -0,0 +1,253 @@
#[derive(PartialEq)]
pub enum Step {
Comment(String),
Dedent,
Format(rnix::SyntaxElement),
FormatWider(rnix::SyntaxElement),
Indent,
NewLine,
Pad,
Token(rnix::SyntaxKind, String),
Whitespace,
}
#[derive(Clone)]
pub struct BuildCtx {
pub config: crate::config::Config,
pub force_wide: bool,
pub indentation: usize,
pub pos_new: crate::position::Position,
pub pos_old: crate::position::Position,
}
impl BuildCtx {
pub fn new(
config: crate::config::Config,
force_wide: bool,
pos_new: crate::position::Position,
pos_old: crate::position::Position,
) -> BuildCtx {
BuildCtx { config, force_wide, indentation: 0, pos_new, pos_old }
}
}
pub fn build(
config: &crate::config::Config,
element: rnix::SyntaxElement,
force_wide: bool,
path: &str,
) -> Option<rowan::GreenNode> {
let mut builder = rowan::GreenNodeBuilder::new();
let mut build_ctx = BuildCtx::new(
config.clone(),
force_wide,
crate::position::Position::new(),
crate::position::Position::new(),
);
build_step(
&mut builder,
&mut build_ctx,
path,
&crate::builder::Step::Format(element),
);
if build_ctx.force_wide && build_ctx.pos_new.line > 1 {
None
} else {
Some(builder.finish())
}
}
fn build_step(
builder: &mut rowan::GreenNodeBuilder,
build_ctx: &mut BuildCtx,
path: &str,
step: &crate::builder::Step,
) {
if build_ctx.force_wide && build_ctx.pos_new.line > 1 {
return;
}
match step {
crate::builder::Step::Comment(text) => {
add_token(
builder,
build_ctx,
rnix::SyntaxKind::TOKEN_COMMENT,
text,
);
}
crate::builder::Step::Dedent => {
build_ctx.indentation -= 1;
}
crate::builder::Step::Format(element) => {
format(builder, build_ctx, element, path);
}
crate::builder::Step::FormatWider(element) => {
format_wider(builder, build_ctx, element, path);
}
crate::builder::Step::Indent => {
build_ctx.indentation += 1;
}
crate::builder::Step::NewLine => {
add_token(
builder,
build_ctx,
rnix::SyntaxKind::TOKEN_WHITESPACE,
"\n",
);
}
crate::builder::Step::Pad => {
if build_ctx.indentation > 0 {
add_token(
builder,
build_ctx,
rnix::SyntaxKind::TOKEN_COMMA,
&format!("{0:<1$}", "", 2 * build_ctx.indentation),
);
}
}
crate::builder::Step::Token(kind, text) => {
add_token(builder, build_ctx, *kind, &text);
}
crate::builder::Step::Whitespace => {
add_token(
builder,
build_ctx,
rnix::SyntaxKind::TOKEN_WHITESPACE,
" ",
);
}
}
}
fn add_token(
builder: &mut rowan::GreenNodeBuilder,
build_ctx: &mut BuildCtx,
kind: rnix::SyntaxKind,
text: &str,
) {
builder.token(rowan::SyntaxKind(kind as u16), text);
build_ctx.pos_new.update(text);
}
fn format(
builder: &mut rowan::GreenNodeBuilder,
build_ctx: &mut BuildCtx,
element: &rnix::SyntaxElement,
path: &str,
) {
let kind = element.kind();
match element {
rnix::SyntaxElement::Node(node) => {
builder.start_node(rowan::SyntaxKind(kind as u16));
let rule = match kind {
rnix::SyntaxKind::NODE_APPLY => crate::rules::apply::rule,
rnix::SyntaxKind::NODE_ASSERT => crate::rules::assert::rule,
rnix::SyntaxKind::NODE_ATTR_SET => crate::rules::attr_set::rule,
rnix::SyntaxKind::NODE_BIN_OP => crate::rules::bin_op::rule,
rnix::SyntaxKind::NODE_DYNAMIC => crate::rules::dynamic::rule,
rnix::SyntaxKind::NODE_ERROR => {
eprintln!("Warning: found an error node at: {}", path);
crate::rules::default
}
rnix::SyntaxKind::NODE_IDENT => crate::rules::default,
rnix::SyntaxKind::NODE_IF_ELSE => crate::rules::if_else::rule,
rnix::SyntaxKind::NODE_INHERIT => crate::rules::inherit::rule,
rnix::SyntaxKind::NODE_INHERIT_FROM => {
crate::rules::inherit_from::rule
}
rnix::SyntaxKind::NODE_KEY => crate::rules::default,
rnix::SyntaxKind::NODE_KEY_VALUE => {
crate::rules::key_value::rule
}
rnix::SyntaxKind::NODE_LAMBDA => crate::rules::lambda::rule,
rnix::SyntaxKind::NODE_LET_IN => crate::rules::let_in::rule,
rnix::SyntaxKind::NODE_LIST => crate::rules::list::rule,
rnix::SyntaxKind::NODE_LITERAL => crate::rules::default,
rnix::SyntaxKind::NODE_LEGACY_LET => {
eprintln!(
"Warning: found a `legacy let` expression at: {}",
path
);
crate::rules::default
}
rnix::SyntaxKind::NODE_OR_DEFAULT => {
crate::rules::or_default::rule
}
rnix::SyntaxKind::NODE_PAREN => crate::rules::paren::rule,
rnix::SyntaxKind::NODE_PAT_BIND => crate::rules::pat_bind::rule,
rnix::SyntaxKind::NODE_PATTERN => crate::rules::pattern::rule,
rnix::SyntaxKind::NODE_PAT_ENTRY => {
crate::rules::pat_entry::rule
}
rnix::SyntaxKind::NODE_PATH_WITH_INTERPOL => {
crate::rules::default
}
rnix::SyntaxKind::NODE_ROOT => crate::rules::root::rule,
rnix::SyntaxKind::NODE_SELECT => crate::rules::select::rule,
rnix::SyntaxKind::NODE_STRING => crate::rules::default,
rnix::SyntaxKind::NODE_STRING_INTERPOL => {
crate::rules::string_interpol::rule
}
rnix::SyntaxKind::NODE_UNARY_OP => crate::rules::default,
rnix::SyntaxKind::NODE_WITH => crate::rules::with::rule,
kind => {
panic!("Missing rule for {:?} at: {}", kind, path);
}
};
for step in rule(build_ctx, node) {
build_step(builder, build_ctx, path, &step);
}
builder.finish_node();
}
rnix::SyntaxElement::Token(token) => {
add_token(builder, build_ctx, kind, token.text());
build_ctx.pos_old.update(token.text());
}
}
}
fn format_wider(
builder: &mut rowan::GreenNodeBuilder,
build_ctx: &mut BuildCtx,
element: &rnix::SyntaxElement,
path: &str,
) {
match element {
rnix::SyntaxElement::Node(node) => {
let maybe_green_node = build(
&build_ctx.config.with_layout(crate::config::Layout::Wide),
node.clone().into(),
true,
path,
);
let layout = match maybe_green_node {
Some(finished) => {
if build_ctx.pos_new.column
+ finished.to_string().chars().count()
> build_ctx.config.max_width()
{
crate::config::Layout::Tall
} else {
crate::config::Layout::Wide
}
}
None => crate::config::Layout::Tall,
};
let mut build_ctx_clone = build_ctx.clone();
build_ctx_clone.config = build_ctx.config.with_layout(layout);
format(builder, &mut build_ctx_clone, element, path);
}
rnix::SyntaxElement::Token(_) => {
format(builder, build_ctx, element, path);
}
};
}

193
src/children.rs Normal file
View file

@ -0,0 +1,193 @@
#[derive(Clone)]
pub struct Child {
pub element: rnix::SyntaxElement,
pub pos: crate::position::Position,
}
pub struct Children {
children: Vec<Child>,
current_index: usize,
}
impl Children {
pub fn new(
build_ctx: &crate::builder::BuildCtx,
node: &rnix::SyntaxNode,
) -> Children {
let mut children = Vec::new();
let mut pos = build_ctx.pos_old.clone();
for child in node.children_with_tokens() {
match child {
rnix::SyntaxElement::Node(_) => {
children
.push(Child { element: child, pos: pos.clone() });
}
rnix::SyntaxElement::Token(token) => {
match token.kind() {
rnix::SyntaxKind::TOKEN_WHITESPACE => {}
_ => {
children.push(Child {
element: token.clone().into(),
pos: pos.clone(),
});
}
}
pos.update(token.text());
}
}
}
Children { children, current_index: 0 }
}
pub fn count(&self) -> usize {
self.children.len()
}
pub fn current_index(&self) -> usize {
self.current_index
}
pub fn get(&mut self, index: usize) -> Option<Child> {
if index + 1 > self.children.len() {
None
} else {
Some(self.children[index].clone())
}
}
pub fn get_next(&mut self) -> Option<Child> {
let child = self.get(self.current_index);
self.move_next();
child
}
pub fn has_next(&self) -> bool {
self.current_index < self.children.len()
}
pub fn peek_next(&mut self) -> Option<Child> {
self.get(self.current_index)
}
pub fn peek_prev(&mut self) -> Option<Child> {
if self.current_index >= 1 {
self.get(self.current_index - 1)
} else {
None
}
}
pub fn move_next(&mut self) {
self.current_index += 1
}
pub fn move_prev(&mut self) {
self.current_index -= 1
}
pub fn has_comments(&self) -> bool {
self.children.iter().any(|child| {
child.element.kind() == rnix::SyntaxKind::TOKEN_COMMENT
})
}
pub fn drain_comment<F: FnMut(String)>(&mut self, mut callback: F) {
if let Some(child) = self.peek_next() {
match child.element.kind() {
rnix::SyntaxKind::TOKEN_COMMENT => {
callback(dedent_comment(
&child.pos,
child.element.into_token().unwrap().text(),
));
self.move_next();
}
_ => {}
}
}
}
pub fn drain_comments<F: FnMut(String)>(&mut self, mut callback: F) {
while let Some(child) = self.peek_next() {
match child.element.kind() {
rnix::SyntaxKind::TOKEN_COMMENT => {
callback(dedent_comment(
&child.pos,
child.element.into_token().unwrap().text(),
));
self.move_next();
}
_ => {
break;
}
}
}
}
}
fn dedent_comment(pos: &crate::position::Position, text: &str) -> String {
if text.starts_with("#") {
text.to_string()
} else {
let text = text[2..text.len() - 2]
.lines()
.enumerate()
.map(|(index, line)| {
if index > 0 {
line.chars()
.skip(if pos.column >= 1 { pos.column - 1 } else { 0 })
.collect::<String>()
} else {
line.to_string()
}
})
.collect::<Vec<String>>()
.join("\n");
format!("/*{}*/", text)
}
}
// fn dedent_string(
// pos: &crate::position::Position,
// node: &rnix::SyntaxNode,
// ) -> String {
// eprintln!("{}", text);
// if text.starts_with("\"") {
// text.to_string()
// } else {
// node.children_with_tokens().filter(|child| {
// child.kind() == rnix::SyntaxKind::TOKEN_STRING_CONTENT
// }).map(|child| {
// let lines = child.into_token().unwrap().lines();
// ""
// " rustup toolchain install nightly"
// " "
// ""
// " "
// });
// // let padding_to_first_char = lines
// // TOKEN_STRING_CONTENT
// let text = text[2..text.len() - 2]
// .lines()
// .enumerate()
// .map(|(index, line)| {
// if index > 0 {
// line.chars()
// .skip(if pos.column >= 1 { pos.column - 1 } else { 0 })
// .collect::<String>()
// } else {
// line.to_string()
// }
// })
// .collect::<Vec<String>>()
// .join("\n");
// format!("/*{}*/", text)
// }
// }

27
src/cli.rs Normal file
View file

@ -0,0 +1,27 @@
pub fn parse(args: Vec<String>) -> clap::ArgMatches {
clap::App::new("alejandra")
.version("v0.1.0")
.about("The uncompromising Nix formatter.")
.arg(
clap::Arg::new("debug")
.help("Enable debug mode.")
.long("debug")
.short('d')
.takes_value(false),
)
.arg(
clap::Arg::new("max-width")
.default_value("120")
.help("How many characters per line to allow.")
.long("max-width")
.takes_value(true)
.value_name("CHARS"),
)
.arg(
clap::Arg::new("paths")
.help("Files or directories, or none to format stdin.")
.multiple_values(true),
)
.term_width(80)
.get_matches_from(args)
}

42
src/config.rs Normal file
View file

@ -0,0 +1,42 @@
#[derive(Clone)]
pub enum Layout {
Tall,
Wide,
}
#[derive(Clone)]
pub struct Config {
debug: bool,
layout: Layout,
max_width: usize,
}
impl Config {
pub fn new() -> Config {
Config { debug: false, layout: Layout::Tall, max_width: 80 }
}
pub fn debug(&self) -> bool {
self.debug
}
pub fn layout(&self) -> &Layout {
&self.layout
}
pub fn max_width(&self) -> usize {
self.max_width
}
pub fn with_debug(&self, debug: bool) -> Config {
Config { debug, layout: self.layout.clone(), max_width: self.max_width }
}
pub fn with_layout(&self, layout: Layout) -> Config {
Config { debug: self.debug, layout, max_width: self.max_width }
}
pub fn with_max_width(&self, max_width: usize) -> Config {
Config { debug: self.debug, layout: self.layout.clone(), max_width }
}
}

27
src/debug.rs Normal file
View file

@ -0,0 +1,27 @@
pub fn display(
element: &rowan::NodeOrToken<&rowan::GreenNodeData, &rowan::GreenTokenData>,
) {
eprintln!("AST:");
display_recursive(element, 2);
}
fn display_recursive(
element: &rowan::NodeOrToken<&rowan::GreenNodeData, &rowan::GreenTokenData>,
depth: usize,
) {
let kind = unsafe {
std::mem::transmute::<u16, rnix::SyntaxKind>(element.kind().0)
};
match element {
rowan::NodeOrToken::Node(node) => {
eprintln!("{0:<1$}{2:?}", "", 2 * depth, kind);
for child in node.children() {
display_recursive(&child, depth + 1);
}
}
rowan::NodeOrToken::Token(token) => {
eprintln!("{0:<1$}{2:?} {3:?}", "", 2 * depth, kind, token.text());
}
}
}

29
src/find.rs Normal file
View file

@ -0,0 +1,29 @@
pub fn nix_files(paths: Vec<&str>) -> Vec<String> {
paths.iter().flat_map(nix_files_in_path).collect()
}
fn nix_files_in_path(path: &&str) -> Vec<String> {
walkdir::WalkDir::new(path)
.into_iter()
.filter_entry(is_nix_file_or_dir)
.filter_map(|entry| match entry {
Ok(entry) => Some(entry),
Err(_) => None,
})
.filter(is_nix_file)
.map(to_full_path)
.collect()
}
fn is_nix_file(entry: &walkdir::DirEntry) -> bool {
entry.file_type().is_file()
&& entry.file_name().to_str().unwrap().ends_with(".nix")
}
fn is_nix_file_or_dir(entry: &walkdir::DirEntry) -> bool {
entry.file_type().is_dir() || is_nix_file(entry)
}
fn to_full_path(entry: walkdir::DirEntry) -> String {
entry.path().to_str().unwrap().to_string()
}

32
src/format.rs Normal file
View file

@ -0,0 +1,32 @@
pub fn string(
config: &crate::config::Config,
path: &str,
string: String,
) -> String {
let tokens = rnix::tokenizer::Tokenizer::new(&string);
let ast = rnix::parser::parse(tokens);
for error in ast.errors() {
eprintln!("Warning: parsing error: {}, at: {}", error, path);
}
let green_node =
crate::builder::build(config, ast.node().into(), false, path).unwrap();
if config.debug() {
crate::debug::display(&(&green_node).into());
}
green_node.to_string()
}
pub fn file(config: &crate::config::Config, path: &str) -> std::io::Result<()> {
use std::io::Write;
let input = std::fs::read_to_string(path)?;
let output = crate::format::string(config, path, input);
std::fs::File::create(path)?.write_all(output.as_bytes())?;
Ok(())
}

9
src/lib.rs Normal file
View file

@ -0,0 +1,9 @@
pub mod builder;
pub mod children;
pub mod cli;
pub mod config;
pub mod debug;
pub mod find;
pub mod format;
pub mod position;
pub mod rules;

33
src/main.rs Normal file
View file

@ -0,0 +1,33 @@
use std::io::Read;
fn main() -> std::io::Result<()> {
let matches = alejandra::cli::parse(std::env::args().collect());
let debug: bool = matches.is_present("debug");
let max_width: usize =
matches.value_of("max-width").unwrap().parse().unwrap();
let config = alejandra::config::Config::new()
.with_debug(debug)
.with_max_width(max_width);
match matches.values_of("paths") {
Some(paths) => {
let paths: Vec<String> =
alejandra::find::nix_files(paths.collect());
eprintln!("Formatting {} files.", paths.len());
for path in paths {
alejandra::format::file(&config, &path)?;
}
}
None => {
eprintln!("Formatting stdin.");
let mut stdin = String::new();
std::io::stdin().read_to_string(&mut stdin).unwrap();
print!("{}", alejandra::format::string(&config, "stdin", stdin));
}
}
std::process::exit(0);
}

24
src/position.rs Normal file
View file

@ -0,0 +1,24 @@
#[derive(Clone, Debug)]
pub struct Position {
pub column: usize,
pub line: usize,
}
impl Position {
pub fn new() -> Position {
Position { column: 0, line: 1 }
}
pub fn update(&mut self, text: &str) {
let chars: Vec<char> = text.chars().collect();
let newlines = chars.iter().filter(|&c| *c == '\n').count();
self.line += newlines;
if newlines > 0 {
self.column = 0
}
self.column += match chars.iter().rposition(|c| *c == '\n') {
Some(pos) => chars.len() - pos,
None => chars.len(),
};
}
}

57
src/rules/apply.rs Normal file
View file

@ -0,0 +1,57 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
match child.element.kind() {
rnix::SyntaxKind::NODE_APPLY => {
steps
.push_back(crate::builder::Step::Format(child.element));
}
_ => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
}
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
steps.push_back(crate::builder::Step::Whitespace);
}
}
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

72
src/rules/assert.rs Normal file
View file

@ -0,0 +1,72 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// assert
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// ;
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

86
src/rules/attr_set.rs Normal file
View file

@ -0,0 +1,86 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// {
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {}
}
loop {
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let Some(child) = children.peek_next() {
let kind = child.element.kind();
if let rnix::SyntaxKind::TOKEN_COMMENT
| rnix::SyntaxKind::TOKEN_CURLY_B_CLOSE = kind
{
break;
}
// item
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
children.move_next();
} else {
break;
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// }
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

85
src/rules/bin_op.rs Normal file
View file

@ -0,0 +1,85 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
match child.element.kind() {
rnix::SyntaxKind::NODE_BIN_OP => {
steps
.push_back(crate::builder::Step::Format(child.element));
}
_ => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
}
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// operator
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

69
src/rules/dynamic.rs Normal file
View file

@ -0,0 +1,69 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// ${
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// }
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

69
src/rules/if_else.rs Normal file
View file

@ -0,0 +1,69 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
for branch in ["if", "then", "else"] {
// if/then/else
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
if branch != "else" {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
if branch != "else" {
steps.push_back(crate::builder::Step::Whitespace);
}
}
}
if branch != "else" {
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
}
}
steps
}

89
src/rules/inherit.rs Normal file
View file

@ -0,0 +1,89 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// inherit
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {}
}
loop {
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let Some(child) = children.peek_next() {
let kind = child.element.kind();
if let rnix::SyntaxKind::TOKEN_COMMENT
| rnix::SyntaxKind::TOKEN_SEMICOLON = kind
{
break;
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
} else {
break;
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
}
// ;
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

64
src/rules/inherit_from.rs Normal file
View file

@ -0,0 +1,64 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

99
src/rules/key_value.rs Normal file
View file

@ -0,0 +1,99 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// a
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// =
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// b
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
// ;
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {}
}
steps
}

66
src/rules/lambda.rs Normal file
View file

@ -0,0 +1,66 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// a
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_next().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// :
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
steps.push_back(crate::builder::Step::Whitespace);
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// c
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

106
src/rules/let_in.rs Normal file
View file

@ -0,0 +1,106 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// let
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {}
}
loop {
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let Some(child) = children.peek_next() {
let kind = child.element.kind();
if let rnix::SyntaxKind::TOKEN_COMMENT
| rnix::SyntaxKind::TOKEN_IN = kind
{
break;
}
// expr
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
children.move_next();
} else {
break;
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// in
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

86
src/rules/list.rs Normal file
View file

@ -0,0 +1,86 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// [
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {}
}
loop {
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let Some(child) = children.peek_next() {
let kind = child.element.kind();
if let rnix::SyntaxKind::TOKEN_COMMENT
| rnix::SyntaxKind::TOKEN_SQUARE_B_CLOSE = kind
{
break;
}
// item
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
children.move_next();
} else {
break;
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// ]
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

43
src/rules/mod.rs Normal file
View file

@ -0,0 +1,43 @@
pub mod apply;
pub mod assert;
pub mod attr_set;
pub mod bin_op;
pub mod dynamic;
pub mod if_else;
pub mod inherit;
pub mod inherit_from;
pub mod key_value;
pub mod lambda;
pub mod let_in;
pub mod list;
pub mod or_default;
pub mod paren;
pub mod pat_bind;
pub mod pat_entry;
pub mod pattern;
pub mod root;
pub mod select;
pub mod string;
pub mod string_interpol;
pub mod with;
pub fn default(
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);
while let Some(child) = children.get_next() {
let step = match build_ctx.config.layout() {
crate::config::Layout::Tall => {
crate::builder::Step::FormatWider(child.element)
}
_ => crate::builder::Step::Format(child.element),
};
steps.push_back(step);
}
steps
}

86
src/rules/or_default.rs Normal file
View file

@ -0,0 +1,86 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
match child.element.kind() {
rnix::SyntaxKind::NODE_OR_DEFAULT => {
steps
.push_back(crate::builder::Step::Format(child.element));
}
_ => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
}
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// operator
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

64
src/rules/paren.rs Normal file
View file

@ -0,0 +1,64 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

53
src/rules/pat_bind.rs Normal file
View file

@ -0,0 +1,53 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
children.move_prev();
steps
}

90
src/rules/pat_entry.rs Normal file
View file

@ -0,0 +1,90 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
match child.element.kind() {
rnix::SyntaxKind::NODE_OR_DEFAULT => {
steps
.push_back(crate::builder::Step::Format(child.element));
}
_ => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
}
steps.push_back(crate::builder::Step::Indent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
if children.has_next() {
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// operator
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
}
steps
}

161
src/rules/pattern.rs Normal file
View file

@ -0,0 +1,161 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// x @
let child = children.peek_next().unwrap();
if let rnix::SyntaxKind::NODE_PAT_BIND = child.element.kind() {
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
steps.push_back(crate::builder::Step::Whitespace);
}
}
children.move_next();
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// {
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
while let Some(child) = children.peek_next() {
match child.element.kind() {
// /**/
rnix::SyntaxKind::TOKEN_COMMENT => {
let prev_kind = children.peek_prev().unwrap().element.kind();
if let rnix::SyntaxKind::TOKEN_COMMA
| rnix::SyntaxKind::TOKEN_CURLY_B_OPEN = prev_kind
{
steps.push_back(crate::builder::Step::Whitespace);
}
if let rnix::SyntaxKind::TOKEN_COMMENT
| rnix::SyntaxKind::TOKEN_ELLIPSIS
| rnix::SyntaxKind::NODE_PAT_ENTRY = prev_kind
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Whitespace);
steps.push_back(crate::builder::Step::Whitespace);
}
children.drain_comment(|text| {
steps.push_back(crate::builder::Step::Comment(text));
});
}
// item
rnix::SyntaxKind::TOKEN_ELLIPSIS
| rnix::SyntaxKind::NODE_PAT_ENTRY => {
let prev_kind = children.peek_prev().unwrap().element.kind();
if let rnix::SyntaxKind::TOKEN_COMMA
| rnix::SyntaxKind::TOKEN_CURLY_B_OPEN = prev_kind
{
steps.push_back(crate::builder::Step::Whitespace);
}
if let rnix::SyntaxKind::TOKEN_COMMENT = prev_kind {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Whitespace);
steps.push_back(crate::builder::Step::Whitespace);
}
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(
child.element,
));
}
};
children.move_next();
}
// ,
rnix::SyntaxKind::TOKEN_COMMA => {
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {}
};
steps.push_back(crate::builder::Step::Format(child.element));
children.move_next();
}
_ => {
break;
}
}
}
// }
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// @ x
if let Some(child) = children.peek_next() {
if let rnix::SyntaxKind::NODE_PAT_BIND = child.element.kind() {
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
}
}
steps
}

45
src/rules/root.rs Normal file
View file

@ -0,0 +1,45 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
while children.has_next() {
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
});
if let Some(child) = children.get_next() {
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
steps.push_back(crate::builder::Step::NewLine);
}
crate::config::Layout::Wide => {
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
}
}
// Trailing newline
if let Some(last_step) = steps.back() {
if *last_step != crate::builder::Step::NewLine {
steps.push_back(crate::builder::Step::NewLine);
}
}
steps
}

77
src/rules/select.rs Normal file
View file

@ -0,0 +1,77 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => match child.element.kind() {
rnix::SyntaxKind::NODE_SELECT => {
steps.push_back(crate::builder::Step::Format(child.element));
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::Indent);
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
},
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// .
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
steps.push_back(crate::builder::Step::Dedent);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

107
src/rules/string.rs Normal file
View file

@ -0,0 +1,107 @@
pub 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 child = children.get_next().unwrap();
let child_token = child.element.clone().into_token().unwrap();
let text = child_token.text();
steps.push_back(crate::builder::Step::Format(child.element));
if text == "\"" {
while let Some(child) = children.get_next() {
match build_ctx.config.layout() {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
}
crate::config::Layout::Wide => {
steps
.push_back(crate::builder::Step::Format(child.element));
}
}
}
} else {
let indentation = get_double_quoted_string_indentation(&node);
while let Some(child) = children.peek_next() {
match child.element.kind() {
rnix::SyntaxKind::TOKEN_STRING_CONTENT => {
let child_token = child.element.into_token().unwrap();
let lines: Vec<&str> =
child_token.text().split('\n').collect();
children.move_next();
for (index, line) in lines.iter().enumerate() {
if index + 1 == lines.len() && line.trim().len() == 0 {
if let rnix::SyntaxKind::TOKEN_STRING_END =
children.peek_next().unwrap().element.kind()
{
continue;
}
}
steps.push_back(crate::builder::Step::Token(
rnix::SyntaxKind::TOKEN_STRING_CONTENT,
if indentation >= line.len() {
line.to_string()
} else {
line[indentation..line.len()].to_string()
},
));
if index == 0 && lines.len() > 1 {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else if index + 1 < lines.len()
&& lines[index + 1].trim().len() == 0
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
}
}
rnix::SyntaxKind::TOKEN_STRING_END => {
steps
.push_back(crate::builder::Step::Format(child.element));
children.move_next();
}
_ => {
steps.push_back(crate::builder::Step::FormatWider(
child.element,
));
children.move_next();
}
}
}
}
// steps = crate::rules::default(build_ctx, node);
steps
}
fn get_double_quoted_string_indentation(node: &rnix::SyntaxNode) -> usize {
let mut indentation: usize = usize::MAX;
let text: String = node
.children_with_tokens()
.filter(|child| child.kind() == rnix::SyntaxKind::TOKEN_STRING_CONTENT)
.map(|child| child.into_token().unwrap())
.map(|token| token.text().to_string())
.collect();
for line in text.split('\n') {
let line = line.trim_end();
if line.len() > 0 {
indentation =
usize::min(indentation, line.len() - line.trim_start().len());
}
}
if indentation == usize::MAX { 0 } else { indentation }
}

View file

@ -0,0 +1,69 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// ${
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Indent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::Comment(text));
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
});
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// }
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::Dedent);
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
}
}
steps.push_back(crate::builder::Step::Format(child.element));
steps
}

72
src/rules/with.rs Normal file
View file

@ -0,0 +1,72 @@
pub 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 layout = if children.has_comments() {
&crate::config::Layout::Tall
} else {
build_ctx.config.layout()
};
// with
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
if let rnix::SyntaxKind::TOKEN_COMMENT =
children.peek_prev().unwrap().element.kind()
{
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
} else {
steps.push_back(crate::builder::Step::Whitespace);
}
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Format(child.element));
}
}
// ;
let child = children.get_next().unwrap();
steps.push_back(crate::builder::Step::Format(child.element));
// /**/
children.drain_comments(|text| {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::Comment(text));
});
// expr
let child = children.get_next().unwrap();
match layout {
crate::config::Layout::Tall => {
steps.push_back(crate::builder::Step::NewLine);
steps.push_back(crate::builder::Step::Pad);
steps.push_back(crate::builder::Step::FormatWider(child.element));
}
crate::config::Layout::Wide => {
steps.push_back(crate::builder::Step::Whitespace);
steps.push_back(crate::builder::Step::Format(child.element));
}
}
steps
}

4
tests/cases/apply/in Normal file
View file

@ -0,0 +1,4 @@
(a b)
(a b)
(a /*b*/ c)
(/*a*/ b /*c*/ d /*e*/)

14
tests/cases/apply/out Normal file
View file

@ -0,0 +1,14 @@
( a b )
( a b )
(
a
/*b*/
c
)
(
/*a*/
b
/*c*/
d
/*e*/
)

8
tests/cases/assert/in Normal file
View file

@ -0,0 +1,8 @@
[
(assert b; c)
(assert b; /*b*/ c)
(assert /*a*/ b; c)
(assert /*a*/ b; /*b*/ c)
( assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc )
( assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc )
]

28
tests/cases/assert/out Normal file
View file

@ -0,0 +1,28 @@
[
( assert b; c )
(
assert b;
/*b*/
c
)
(
assert
/*a*/
b;
c
)
(
assert
/*a*/
b;
/*b*/
c
)
(
assert b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
)
(
assert b;
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
)
]

7
tests/cases/attr_set/in Normal file
View file

@ -0,0 +1,7 @@
[
{}
{/*a*/}
{a=1;}
{/*a*/b=1;/*c*/}
{a={a={a={a={a={a={a={a={a={a={};};};};};};};};};};}
]

24
tests/cases/attr_set/out Normal file
View file

@ -0,0 +1,24 @@
[
{ }
{
/*a*/
}
{ a = 1; }
{
/*a*/
b = 1;
/*c*/
}
{
a =
{
a =
{
a =
{
a = { a = { a = { a = { a = { a = { a = { }; }; }; }; }; }; };
};
};
};
}
]

9
tests/cases/bin_op/in Normal file
View file

@ -0,0 +1,9 @@
[
(1 + 1)
(1 +/**/1)
(1/**/+ 1)
(1/**/+/**/1)
(1/**/+/**/(1/**/+/**/(1/**/+/**/1)))
( 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 )
( 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1)
]

63
tests/cases/bin_op/out Normal file
View file

@ -0,0 +1,63 @@
[
( 1 + 1 )
(
1
+
/**/
1
)
(
1
/**/
+ 1
)
(
1
/**/
+
/**/
1
)
(
1
/**/
+
/**/
(
1
/**/
+
/**/
(
1
/**/
+
/**/
1
)
)
)
( 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 )
(
1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
+ 1
)
]

1
tests/cases/dynamic/in Normal file
View file

@ -0,0 +1 @@
a.${/*b*/c.${/*d*/e.${f}}/*g*/}

10
tests/cases/dynamic/out Normal file
View file

@ -0,0 +1,10 @@
a
.${
/*b*/
c
.${
/*d*/
e.${ f }
}
/*g*/
}

4
tests/cases/if_else/in Normal file
View file

@ -0,0 +1,4 @@
[
(if a then b else c)
(if /**/ a /**/ then /**/ b /**/ else /**/ c)
]

16
tests/cases/if_else/out Normal file
View file

@ -0,0 +1,16 @@
[
( if a then b else c )
(
if
/**/
a
/**/
then
/**/
b
/**/
else
/**/
c
)
]

12
tests/cases/inherit/in Normal file
View file

@ -0,0 +1,12 @@
[
{ inherit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; }
{ inherit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; }
{ inherit b d ; }
{ inherit b d /*e*/ ; }
{ inherit b /*c*/ d ; }
{ inherit b /*c*/ d /*e*/ ; }
{ inherit /*a*/ b d ; }
{ inherit /*a*/ b d /*e*/ ; }
{ inherit /*a*/ b /*c*/ d ; }
{ inherit /*a*/ b /*c*/ d /*e*/ ; }
]

61
tests/cases/inherit/out Normal file
View file

@ -0,0 +1,61 @@
[
{
inherit aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
}
{
inherit
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;
}
{ inherit b d; }
{
inherit
b
d
/*e*/
;
}
{
inherit
b
/*c*/
d;
}
{
inherit
b
/*c*/
d
/*e*/
;
}
{
inherit
/*a*/
b
d;
}
{
inherit
/*a*/
b
d
/*e*/
;
}
{
inherit
/*a*/
b
/*c*/
d;
}
{
inherit
/*a*/
b
/*c*/
d
/*e*/
;
}
]

View file

@ -0,0 +1,6 @@
[
{ inherit ( b ) d; }
{ inherit ( b /*c*/) d; }
{ inherit (/*a*/ b ) d; }
{ inherit (/*a*/ b /*c*/) d; }
]

View file

@ -0,0 +1,28 @@
[
{ inherit ( b ) d; }
{
inherit
(
b
/*c*/
)
d;
}
{
inherit
(
/*a*/
b
)
d;
}
{
inherit
(
/*a*/
b
/*c*/
)
d;
}
]

10
tests/cases/key_value/in Normal file
View file

@ -0,0 +1,10 @@
{
a = {a = 1 ;};
b = {a = 1/*d*/;};
c = {a =/*c*/1 ;};
d = {a =/*c*/1/*d*/;};
e = {a/*b*/= 1 ;};
f = {a/*b*/= 1/*d*/;};
h = {a/*b*/=/*c*/1 ;};
i = {a/*b*/=/*c*/1/*d*/;};
}

58
tests/cases/key_value/out Normal file
View file

@ -0,0 +1,58 @@
{
a = { a = 1; };
b =
{
a =
1
/*d*/
;
};
c =
{
a =
/*c*/
1;
};
d =
{
a =
/*c*/
1
/*d*/
;
};
e =
{
a
/*b*/
=
1;
};
f =
{
a
/*b*/
=
1
/*d*/
;
};
h =
{
a
/*b*/
=
/*c*/
1;
};
i =
{
a
/*b*/
=
/*c*/
1
/*d*/
;
};
}

10
tests/cases/lambda/in Normal file
View file

@ -0,0 +1,10 @@
[
(a : d)
(a : /*c*/ d)
(a /*b*/ : d)
(a /*b*/ : /*c*/ d)
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa )
]

28
tests/cases/lambda/out Normal file
View file

@ -0,0 +1,28 @@
[
( a: d )
(
a:
/*c*/
d
)
(
a
/*b*/
:
d
)
(
a
/*b*/
:
/*c*/
d
)
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
(
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
)
]

21
tests/cases/let_in/in Normal file
View file

@ -0,0 +1,21 @@
let
/**/
a = let c=1; in f;
/**/
a = let c=1; in /*e*/ f;
/**/
a = let c=1; /*d*/ in f;
/**/
a = let c=1; /*d*/ in /*e*/ f;
/**/
a = let /*b*/ c=1; in f;
/**/
a = let /*b*/ c=1; in /*e*/ f;
/**/
a = let /*b*/ c=1; /*d*/ in f;
/**/
a = let /*b*/ c=1; /*d*/ in /*e*/ f;
/**/
in
/**/
a

61
tests/cases/let_in/out Normal file
View file

@ -0,0 +1,61 @@
let
/**/
a = let c = 1; in f;
/**/
a =
let
c = 1;
in
/*e*/
f;
/**/
a =
let
c = 1;
/*d*/
in
f;
/**/
a =
let
c = 1;
/*d*/
in
/*e*/
f;
/**/
a =
let
/*b*/
c = 1;
in
f;
/**/
a =
let
/*b*/
c = 1;
in
/*e*/
f;
/**/
a =
let
/*b*/
c = 1;
/*d*/
in
f;
/**/
a =
let
/*b*/
c = 1;
/*d*/
in
/*e*/
f;
/**/
in
/**/
a

View file

@ -0,0 +1,9 @@
[
(a ? a)
(a ?/**/a)
(a/**/? a)
(a/**/?/**/a)
(a/**/?/**/(a/**/?/**/(a/**/?/**/a)))
( a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a )
( a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a)
]

View file

@ -0,0 +1,63 @@
[
( a ? a )
(
a
?
/**/
a
)
(
a
/**/
? a
)
(
a
/**/
?
/**/
a
)
(
a
/**/
?
/**/
(
a
/**/
?
/**/
(
a
/**/
?
/**/
a
)
)
)
( a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a ? a )
(
a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
? a
)
]

1
tests/cases/paren/in Normal file
View file

@ -0,0 +1 @@
(/*a*/(/*b*/(c))/*d*/)

8
tests/cases/paren/out Normal file
View file

@ -0,0 +1,8 @@
(
/*a*/
(
/*b*/
( c )
)
/*d*/
)

11
tests/cases/pat_bind/in Normal file
View file

@ -0,0 +1,11 @@
[
({} @ a: _)
({} @ /**/ a: _)
({} /**/ @ a: _)
({} /**/ @ /**/ a: _)
(a @ {}: _)
(a @ /**/ {}: _)
(a /**/ @ {}: _)
(a /**/ @ /**/ {}: _)
]

52
tests/cases/pat_bind/out Normal file
View file

@ -0,0 +1,52 @@
[
( { } @ a: _ )
(
{
}
@
/**/
a:
_
)
(
{
}
/**/
@ a:
_
)
(
{
}
/**/
@
/**/
a:
_
)
( a @ { }: _ )
(
a @
/**/
{
}:
_
)
(
a
/**/
@
{
}:
_
)
(
a
/**/
@
/**/
{
}:
_
)
]

73
tests/cases/pattern/in Normal file
View file

@ -0,0 +1,73 @@
[
({}: _)
({ /**/ }: _)
({ ... }: _)
({ ... /**/}: _)
({ /**/ ... }: _)
({ /**/ ... /**/}: _)
({ b , e , ... }: _)
({ b , e , ... /*h*/ }: _)
({ b , e , /*g*/ ... }: _)
({ b , e , /*g*/ ... /*h*/ }: _)
({ b , e /*f*/ , ... }: _)
({ b , e /*f*/ , ... /*h*/ }: _)
({ b , e /*f*/ , /*g*/ ... }: _)
({ b , e /*f*/ , /*g*/ ... /*h*/ }: _)
({ b , /*d*/ e , ... }: _)
({ b , /*d*/ e , ... /*h*/ }: _)
({ b , /*d*/ e , /*g*/ ... }: _)
({ b , /*d*/ e , /*g*/ ... /*h*/ }: _)
({ b , /*d*/ e /*f*/ , ... }: _)
({ b , /*d*/ e /*f*/ , ... /*h*/ }: _)
({ b , /*d*/ e /*f*/ , /*g*/ ... }: _)
({ b , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _)
({ b /*c*/ , e , ... }: _)
({ b /*c*/ , e , ... /*h*/ }: _)
({ b /*c*/ , e , /*g*/ ... }: _)
({ b /*c*/ , e , /*g*/ ... /*h*/ }: _)
({ b /*c*/ , e /*f*/ , ... }: _)
({ b /*c*/ , e /*f*/ , ... /*h*/ }: _)
({ b /*c*/ , e /*f*/ , /*g*/ ... }: _)
({ b /*c*/ , e /*f*/ , /*g*/ ... /*h*/ }: _)
({ b /*c*/ , /*d*/ e , ... }: _)
({ b /*c*/ , /*d*/ e , ... /*h*/ }: _)
({ b /*c*/ , /*d*/ e , /*g*/ ... }: _)
({ b /*c*/ , /*d*/ e , /*g*/ ... /*h*/ }: _)
({ b /*c*/ , /*d*/ e /*f*/ , ... }: _)
({ b /*c*/ , /*d*/ e /*f*/ , ... /*h*/ }: _)
({ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... }: _)
({ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _)
({ /*a*/ b , e , ... }: _)
({ /*a*/ b , e , ... /*h*/ }: _)
({ /*a*/ b , e , /*g*/ ... }: _)
({ /*a*/ b , e , /*g*/ ... /*h*/ }: _)
({ /*a*/ b , e /*f*/ , ... }: _)
({ /*a*/ b , e /*f*/ , ... /*h*/ }: _)
({ /*a*/ b , e /*f*/ , /*g*/ ... }: _)
({ /*a*/ b , e /*f*/ , /*g*/ ... /*h*/ }: _)
({ /*a*/ b , /*d*/ e , ... }: _)
({ /*a*/ b , /*d*/ e , ... /*h*/ }: _)
({ /*a*/ b , /*d*/ e , /*g*/ ... }: _)
({ /*a*/ b , /*d*/ e , /*g*/ ... /*h*/ }: _)
({ /*a*/ b , /*d*/ e /*f*/ , ... }: _)
({ /*a*/ b , /*d*/ e /*f*/ , ... /*h*/ }: _)
({ /*a*/ b , /*d*/ e /*f*/ , /*g*/ ... }: _)
({ /*a*/ b , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _)
({ /*a*/ b /*c*/ , e , ... }: _)
({ /*a*/ b /*c*/ , e , ... /*h*/ }: _)
({ /*a*/ b /*c*/ , e , /*g*/ ... }: _)
({ /*a*/ b /*c*/ , e , /*g*/ ... /*h*/ }: _)
({ /*a*/ b /*c*/ , e /*f*/ , ... }: _)
({ /*a*/ b /*c*/ , e /*f*/ , ... /*h*/ }: _)
({ /*a*/ b /*c*/ , e /*f*/ , /*g*/ ... }: _)
({ /*a*/ b /*c*/ , e /*f*/ , /*g*/ ... /*h*/ }: _)
({ /*a*/ b /*c*/ , /*d*/ e , ... }: _)
({ /*a*/ b /*c*/ , /*d*/ e , ... /*h*/ }: _)
({ /*a*/ b /*c*/ , /*d*/ e , /*g*/ ... }: _)
({ /*a*/ b /*c*/ , /*d*/ e , /*g*/ ... /*h*/ }: _)
({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , ... }: _)
({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , ... /*h*/ }: _)
({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... }: _)
({ /*a*/ b /*c*/ , /*d*/ e /*f*/ , /*g*/ ... /*h*/ }: _)
]

662
tests/cases/pattern/out Normal file
View file

@ -0,0 +1,662 @@
[
( { }: _ )
(
{ /**/
}:
_
)
( { ... }: _ )
(
{ ...
/**/
}:
_
)
(
{ /**/
...
}:
_
)
(
{ /**/
...
/**/
}:
_
)
( { b, e, ... }: _ )
(
{ b
, e
, ...
/*h*/
}:
_
)
(
{ b
, e
, /*g*/
...
}:
_
)
(
{ b
, e
, /*g*/
...
/*h*/
}:
_
)
(
{ b
, e
/*f*/
, ...
}:
_
)
(
{ b
, e
/*f*/
, ...
/*h*/
}:
_
)
(
{ b
, e
/*f*/
, /*g*/
...
}:
_
)
(
{ b
, e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ b
, /*d*/
e
, ...
}:
_
)
(
{ b
, /*d*/
e
, ...
/*h*/
}:
_
)
(
{ b
, /*d*/
e
, /*g*/
...
}:
_
)
(
{ b
, /*d*/
e
, /*g*/
...
/*h*/
}:
_
)
(
{ b
, /*d*/
e
/*f*/
, ...
}:
_
)
(
{ b
, /*d*/
e
/*f*/
, ...
/*h*/
}:
_
)
(
{ b
, /*d*/
e
/*f*/
, /*g*/
...
}:
_
)
(
{ b
, /*d*/
e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ b
/*c*/
, e
, ...
}:
_
)
(
{ b
/*c*/
, e
, ...
/*h*/
}:
_
)
(
{ b
/*c*/
, e
, /*g*/
...
}:
_
)
(
{ b
/*c*/
, e
, /*g*/
...
/*h*/
}:
_
)
(
{ b
/*c*/
, e
/*f*/
, ...
}:
_
)
(
{ b
/*c*/
, e
/*f*/
, ...
/*h*/
}:
_
)
(
{ b
/*c*/
, e
/*f*/
, /*g*/
...
}:
_
)
(
{ b
/*c*/
, e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ b
/*c*/
, /*d*/
e
, ...
}:
_
)
(
{ b
/*c*/
, /*d*/
e
, ...
/*h*/
}:
_
)
(
{ b
/*c*/
, /*d*/
e
, /*g*/
...
}:
_
)
(
{ b
/*c*/
, /*d*/
e
, /*g*/
...
/*h*/
}:
_
)
(
{ b
/*c*/
, /*d*/
e
/*f*/
, ...
}:
_
)
(
{ b
/*c*/
, /*d*/
e
/*f*/
, ...
/*h*/
}:
_
)
(
{ b
/*c*/
, /*d*/
e
/*f*/
, /*g*/
...
}:
_
)
(
{ b
/*c*/
, /*d*/
e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
, e
, ...
}:
_
)
(
{ /*a*/
b
, e
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
, e
, /*g*/
...
}:
_
)
(
{ /*a*/
b
, e
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
, e
/*f*/
, ...
}:
_
)
(
{ /*a*/
b
, e
/*f*/
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
, e
/*f*/
, /*g*/
...
}:
_
)
(
{ /*a*/
b
, e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
, /*d*/
e
, ...
}:
_
)
(
{ /*a*/
b
, /*d*/
e
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
, /*d*/
e
, /*g*/
...
}:
_
)
(
{ /*a*/
b
, /*d*/
e
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
, /*d*/
e
/*f*/
, ...
}:
_
)
(
{ /*a*/
b
, /*d*/
e
/*f*/
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
, /*d*/
e
/*f*/
, /*g*/
...
}:
_
)
(
{ /*a*/
b
, /*d*/
e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, e
, ...
}:
_
)
(
{ /*a*/
b
/*c*/
, e
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, e
, /*g*/
...
}:
_
)
(
{ /*a*/
b
/*c*/
, e
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, e
/*f*/
, ...
}:
_
)
(
{ /*a*/
b
/*c*/
, e
/*f*/
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, e
/*f*/
, /*g*/
...
}:
_
)
(
{ /*a*/
b
/*c*/
, e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
, ...
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
, /*g*/
...
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
, /*g*/
...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
/*f*/
, ...
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
/*f*/
, ...
/*h*/
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
/*f*/
, /*g*/
...
}:
_
)
(
{ /*a*/
b
/*c*/
, /*d*/
e
/*f*/
, /*g*/
...
/*h*/
}:
_
)
]

14
tests/cases/root/in Normal file
View file

@ -0,0 +1,14 @@
# a
/* test
* test
*/
# a
"test"
# b
/* c */
/* c */
# c

10
tests/cases/root/out Normal file
View file

@ -0,0 +1,10 @@
# a
/* test
* test
*/
# a
"test"
# b
/* c */
/* c */
# c

8
tests/cases/select/in Normal file
View file

@ -0,0 +1,8 @@
[
(a . a)
(a ./**/a)
(a/**/. a)
(a/**/./**/a)
( a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a )
( a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a )
]

65
tests/cases/select/out Normal file
View file

@ -0,0 +1,65 @@
[
( a.a )
(
a
.
/**/
a
)
(
a
/**/
.a
)
(
a
/**/
.
/**/
a
)
(
a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a
)
(
a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
.a
)
]

40
tests/cases/string/in Normal file
View file

@ -0,0 +1,40 @@
[
""
"
"
"a
${x}
b
"
''''
''a''
''${""}''
''
a
${""}
b
${""}
c ${""} d
e
''
''
''
''
declare -a makefiles=(./*.mak)
sed -i -f ${makefile-sed} "''${makefiles[@]}"
# assign Makefile variables eagerly & change backticks to `$(shell …)`
sed -i -e 's/ = `\([^`]\+\)`/ := $(shell \1)/' \
-e 's/`\([^`]\+\)`/$(shell \1)/' \
"''${makefiles[@]}"
''
]

30
tests/cases/string/out Normal file
View file

@ -0,0 +1,30 @@
[
""
"
"
"a
${ x }
b
"
''''
''a''
''${ "" }''
''
a
${ "" }
b
${ "" }
c ${ "" } d
e
''
''
''
''
declare -a makefiles=(./*.mak)
sed -i -f ${ makefile-sed } "''${makefiles[@]}"
# assign Makefile variables eagerly & change backticks to `$(shell …)`
sed -i -e 's/ = `\([^`]\+\)`/ := $(shell \1)/' \
-e 's/`\([^`]\+\)`/$(shell \1)/' \
"''${makefiles[@]}"
''
]

View file

@ -0,0 +1 @@
"${/*a*/"${/*b*/"${c}"}"/*d*/}"

View file

@ -0,0 +1,8 @@
"${
/*a*/
"${
/*b*/
"${ c }"
}"
/*d*/
}"

8
tests/cases/with/in Normal file
View file

@ -0,0 +1,8 @@
[
(with b; c)
(with b; /*b*/ c)
(with /*a*/ b; c)
(with /*a*/ b; /*b*/ c)
( with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc )
( with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc )
]

28
tests/cases/with/out Normal file
View file

@ -0,0 +1,28 @@
[
( with b; c )
(
with b;
/*b*/
c
)
(
with
/*a*/
b;
c
)
(
with
/*a*/
b;
/*b*/
c
)
(
with b; cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
)
(
with b;
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
)
]

52
tests/fmt.rs Normal file
View file

@ -0,0 +1,52 @@
use std::io::Write;
#[test]
fn cases() {
let should_update = std::env::var("UPDATE").is_ok();
let config = alejandra::config::Config::new();
let cases: std::collections::HashSet<String> =
std::fs::read_dir("tests/cases")
.unwrap()
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
.collect();
for case in cases {
let path_in = format!("tests/cases/{}/in", case);
let path_out = format!("tests/cases/{}/out", case);
let content_in = std::fs::read_to_string(path_in.clone()).unwrap();
let content_got =
alejandra::format::string(&config, &path_in, content_in.clone());
if should_update {
std::fs::File::create(&path_out)
.unwrap()
.write_all(content_got.as_bytes())
.unwrap();
}
let content_out = std::fs::read_to_string(path_out.clone()).unwrap();
assert!(
content_got == content_out,
indoc::indoc!(
r"
input from {}:
{}
after formatting:
{}
expected from {}:
{}
"
),
path_in,
&content_in,
&content_got,
path_out,
&content_out,
);
}
}