use ec4rs::property::{self, FinalNewline};
use line_ending::LineEnding;
use snafu::ensure;
use crate::{errors, files};
use super::{PropertyHandler, charset, end_of_line};
pub struct InsertFinalNewLineHandler {
charset: property::Charset,
line_ending: LineEnding,
}
impl PropertyHandler for InsertFinalNewLineHandler {
fn check(&self, file_path: &std::path::Path) -> anyhow::Result<()> {
let content = files::read_file(file_path, &self.charset)?;
let needs_final_newline = self.needs_final_newline(&content);
ensure!(!needs_final_newline, errors::InsertFinalNewlineSnafu {});
Ok(())
}
fn fix(&self, file_path: &std::path::Path) -> anyhow::Result<()> {
let mut content = files::read_file(file_path, &self.charset)?;
if self.add_final_newline(&mut content) {
files::overwrite_file(file_path, &self.charset, &content)?;
}
Ok(())
}
}
impl InsertFinalNewLineHandler {
pub fn build(properties: &ec4rs::Properties) -> Option<InsertFinalNewLineHandler> {
match properties.get::<property::FinalNewline>() {
Ok(FinalNewline::Value(true)) => Some(InsertFinalNewLineHandler {
charset: charset::get_charset(properties),
line_ending: end_of_line::get_line_ending(properties),
}),
Ok(FinalNewline::Value(false)) | Err(_) => None,
}
}
fn needs_final_newline(&self, content: &str) -> bool {
!content.is_empty() && !content.ends_with(self.line_ending.as_str())
}
fn add_final_newline(&self, content: &mut String) -> bool {
let needs_final_newline = self.needs_final_newline(content);
if needs_final_newline {
content.push_str(self.line_ending.as_str());
}
needs_final_newline
}
}
#[cfg(test)]
mod tests;