//! Copyright (C) 2022, Dmitriy Pleshevskiy //! //! vnetod is free software: you can redistribute it and/or modify //! it under the terms of the GNU General Public License as published by //! the Free Software Foundation, either version 3 of the License, or //! (at your option) any later version. //! //! vnetod is distributed in the hope that it will be useful, //! but WITHOUT ANY WARRANTY; without even the implied warranty of //! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //! GNU General Public License for more details. //! //! You should have received a copy of the GNU General Public License //! along with vnetod. If not, see . //! #[cfg(feature = "color")] use termcolor::{Color, ColorSpec, StandardStream, WriteColor}; use crate::{cli::Args, domain}; use std::fs::File; use std::io::Write; #[derive(Debug)] pub enum Error { OpenFile, WriteFile, } impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::OpenFile => f.write_str("Cannot open file"), Error::WriteFile => f.write_str("Cannot write file"), } } } impl std::error::Error for Error {} pub fn execute(args: &Args) -> Result<(), Error> { let content = std::fs::read_to_string(&args.file).map_err(|_| Error::OpenFile)?; if args.dry_run { println!("Your file will be changed to the following") } let fs_writer = (!args.dry_run) .then(|| { File::create(args.output.as_ref().unwrap_or(&args.file)).map_err(|_| Error::OpenFile) }) .transpose()?; #[cfg(feature = "color")] let color = args.color.clone(); println!(); let new_content = domain::switch::execute(domain::switch::Request { content: &content.trim(), sections: &args.sections, on_line: Some(Box::new(move |line| { #[cfg(feature = "color")] print_line(line, color.clone()); #[cfg(not(feature = "color"))] print!("{}", line) })), }); println!(); if let Some(mut fs_writer) = fs_writer { fs_writer .write_all(new_content.as_bytes()) .map_err(|_| Error::WriteFile)?; } Ok(()) } #[cfg(feature = "color")] fn print_line(line: &String, color: crate::cli::ColorVariant) { let mut stdout = StandardStream::stdout(color.into()); let color = line .starts_with("###") .then_some(Color::Yellow) .or_else(|| (!line.starts_with("#")).then_some(Color::Green)); stdout.set_color(ColorSpec::new().set_fg(color)).ok(); write!(&mut stdout, "{}", line).unwrap(); stdout.reset().ok(); }