#[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),
}
}