alejandra 1.5.0

The Uncompromising Nix Code Formatter
Documentation
#[derive(Clone)]
pub enum Status {
    Error(String),
    Changed(bool),
}

impl From<std::io::Error> for Status {
    fn from(error: std::io::Error) -> Status {
        Status::Error(error.to_string())
    }
}

pub fn in_memory(path: String, before: String) -> (Status, String) {
    let tokens = rnix::tokenizer::Tokenizer::new(&before);
    let ast = rnix::parser::parse(tokens);

    let errors = ast.errors();
    if !errors.is_empty() {
        return (Status::Error(errors[0].to_string()), before);
    }

    let mut build_ctx = crate::builder::BuildCtx {
        force_wide: false,
        force_wide_success: true,
        indentation: 0,
        path,
        pos_old: crate::position::Position::default(),
        vertical: true,
    };

    let after = crate::builder::build(&mut build_ctx, ast.node().into())
        .unwrap()
        .to_string();

    if before == after {
        (Status::Changed(false), after)
    } else {
        (Status::Changed(true), after)
    }
}

pub fn in_fs(path: String, in_place: bool) -> Status {
    use std::io::Write;

    match std::fs::read_to_string(&path) {
        Ok(before) => {
            let (status, data) = crate::format::in_memory(path.clone(), before);

            match status {
                Status::Changed(changed) => {
                    if in_place {
                        if changed {
                            match std::fs::File::create(path) {
                                Ok(mut file) => {
                                    match file.write_all(data.as_bytes()) {
                                        Ok(_) => Status::Changed(true),
                                        Err(error) => Status::from(error),
                                    }
                                }
                                Err(error) => Status::from(error),
                            }
                        } else {
                            Status::Changed(false)
                        }
                    } else {
                        Status::Changed(changed)
                    }
                }
                Status::Error(error) => Status::Error(error),
            }
        }
        Err(error) => Status::from(error),
    }
}