use crate::{Replacer, Result, edit::Edit, patcher::Patcher, writer::Writer, output::OutputType};
use std::io::prelude::*;
use std::fs::File;
pub(crate) struct App {
replacer: Option<Replacer>
}
impl App {
pub(crate) fn new(replacer: Option<Replacer>) -> Self {
Self { replacer }
}
pub(crate) fn run(&self, preview: bool, delete: bool, color: bool, pager: Option<String>) -> Result<()> {
{
let stdin = std::io::stdin();
let handle = stdin.lock();
let mut output_type = match OutputType::for_pager(pager, true) {
Ok(output_type) => output_type,
Err(_) => return Ok(()), };
let write = match output_type.handle() {
Ok(write) => write,
Err(_) => return Ok(()), };
match Edit::parse(handle) {
Ok(path_to_edits) => {
if preview {
for (path, edits) in path_to_edits {
let patcher = Patcher::new(edits, self.replacer.as_ref());
if let Err(_) = Self::check_not_empty(File::open(&path)?) {
continue }
let writer = Writer::new(path.to_path_buf(), &patcher);
let text = match writer.patch_preview(color, delete) {
Ok(text) => text,
Err(_) => continue, };
write!(write, "{}", text)?;
}
} else {
for (path, edits) in path_to_edits {
let patcher = Patcher::new(edits, self.replacer.as_ref());
if let Err(_) = Self::check_not_empty(File::open(&path)?) {
return Ok(()); }
let writer = Writer::new(path, &patcher);
if let Err(_) = writer.write_file(delete) {
return Ok(()); }
}
}
},
Err(_) => {
return Ok(()); },
}
drop(output_type);
}
Ok(())
}
pub(crate) fn check_not_empty(mut file: File) -> Result<()> {
let mut buf: [u8; 1] = Default::default();
file.read_exact(&mut buf)?;
Ok(())
}
}