diff options
author | Canop <cano.petrole@gmail.com> | 2020-04-15 14:01:20 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2020-04-15 14:01:20 +0200 |
commit | 0e5f471527721cf94347dabb6d4e8b606e3f6db2 (patch) | |
tree | ee2d08f16abd6ea73072bf8d599d561fc99f105a /src/external.rs | |
parent | f9c5b49358ec1654cceed5aacc8620bf060acb4d (diff) |
refactor verbs for more type enforced sanity
Diffstat (limited to 'src/external.rs')
-rw-r--r-- | src/external.rs | 209 |
1 files changed, 0 insertions, 209 deletions
diff --git a/src/external.rs b/src/external.rs deleted file mode 100644 index 3786f2f..0000000 --- a/src/external.rs +++ /dev/null @@ -1,209 +0,0 @@ -use { - crate::{ - app::{ - AppContext, - AppStateCmdResult, - }, - displayable_tree::DisplayableTree, - errors::ProgramError, - flat_tree::Tree, - screens::Screen, - skin::Skin, - }, - open, - pathdiff, - regex::Regex, - std::{ - env, - fs::OpenOptions, - io::{self, Write}, - path::{Path, PathBuf}, - process::Command, - }, -}; - -/// description of a possible launch of an external program -/// A launchable can only be executed on end of life of broot. -#[derive(Debug)] -pub enum Launchable { - Printer { - // just print something on stdout on end of broot - to_print: String, - }, - TreePrinter { - // print the tree on end of broot - tree: Box<Tree>, - skin: Box<Skin>, - width: u16, - }, - Program { - // execute an external program - exe: String, - args: Vec<String>, - }, - SystemOpen { - // open a path - path: PathBuf, - }, -} - -/// If a part starts by a '$', replace it by the environment variable of the same name. -/// This part is splitted too (because of https://github.com/Canop/broot/issues/114) -fn resolve_env_variables(parts: Vec<String>) -> Vec<String> { - let mut resolved = Vec::new(); - for part in parts.into_iter() { - if part.starts_with('$') { - if let Ok(val) = env::var(&part[1..]) { - resolved.extend(val.split(' ').map(|s| s.to_string())); - continue; - } - } - resolved.push(part); - } - resolved -} - -impl Launchable { - pub fn opener(path: PathBuf) -> Launchable { - Launchable::SystemOpen { path } - } - pub fn printer(to_print: String) -> Launchable { - Launchable::Printer { to_print } - } - pub fn tree_printer( - tree: &Tree, - screen: &Screen, - no_style: bool, - ) -> Launchable { - Launchable::TreePrinter { - tree: Box::new(tree.clone()), - skin: Box::new( - if no_style { - Skin::no_term() - } else { - screen.skin.clone() - } - ), - width: screen.width, - } - } - - pub fn program(parts: Vec<String>) -> io::Result<Launchable> { - let mut parts = resolve_env_variables(parts).into_iter(); - match parts.next() { - Some(exe) => Ok(Launchable::Program { - exe, - args: parts.collect(), - }), - None => Err(io::Error::new(io::ErrorKind::Other, "Empty launch string")), - } - } - - pub fn execute(&self) -> Result<(), ProgramError> { - match self { - Launchable::Printer { to_print } => { - println!("{}", to_print); - Ok(()) - } - Launchable::TreePrinter { tree, skin, width } => { - let dp = DisplayableTree::out_of_app(&tree, &skin, *width); - dp.write_on(&mut std::io::stdout()) - } - Launchable::Program { exe, args } => { - Command::new(&exe) - .args(args.iter()) - .spawn() - .and_then(|mut p| p.wait()) - .map_err(|source| ProgramError::LaunchError { - program: exe.clone(), - source, - })?; - Ok(()) - } - Launchable::SystemOpen { path } => { - open::that(&path)?; - Ok(()) - } - } - } -} - -// from a path, build a string usable in a shell command, wrapping -// it in quotes if necessary (and then escaping internal quotes). -// Don't do unnecessary transformation, so that the produced string -// is prettier on screen. -pub fn escape_for_shell(path: &Path) -> String { - let path = path.to_string_lossy(); - if regex!(r"^[\w/.-]*$").is_match(&path) { - path.to_string() - } else { - format!("'{}'", &path.replace('\'', r"'\''")) - } -} - -pub fn print_path(path: &Path, con: &AppContext) -> io::Result<AppStateCmdResult> { - let path = path.to_string_lossy().to_string(); - Ok( - if let Some(ref output_path) = con.launch_args.file_export_path { - // an output path was provided, we write to it - let f = OpenOptions::new() - .create(true) - .append(true) - .open(output_path)?; - writeln!(&f, "{}", path)?; - AppStateCmdResult::Quit - } else { - // no output path provided. We write on stdout, but we must - // do it after app closing to have the normal terminal - AppStateCmdResult::from(Launchable::printer(path)) - }, - ) -} - -pub fn print_relative_path(path: &Path, con: &AppContext) -> io::Result<AppStateCmdResult> { - let relative_path = match pathdiff::diff_paths(path, &con.launch_args.root) { - None => return Ok(AppStateCmdResult::DisplayError( - format!("Cannot relativize {:?}", path) // does this happen ? how ? - )), - Some(p) => p, - }; - if relative_path.components().next().is_some() { - print_path(&relative_path, con) - } else { - print_path(Path::new("."), con) - } -} - -fn print_tree_to_file( - tree: &Tree, - screen: &mut Screen, - file_path: &str, -) -> Result<AppStateCmdResult, ProgramError> { - let no_style_skin = Skin::no_term(); - let dp = DisplayableTree::out_of_app(tree, &no_style_skin, screen.width); - let mut f = OpenOptions::new() - .create(true) - .append(true) - .open(file_path)?; - dp.write_on(&mut f)?; - Ok(AppStateCmdResult::Quit) -} - -pub fn print_tree( - tree: &Tree, - screen: &mut Screen, - con: &AppContext, -) -> Result<AppStateCmdResult, ProgramError> { - if let Some(ref output_path) = con.launch_args.file_export_path { - // an output path was provided, we write to it - print_tree_to_file(tree, screen, output_path) - } else { - // no output path provided. We write on stdout, but we must - // do it after app closing to have the normal terminal - Ok(AppStateCmdResult::from(Launchable::tree_printer( - tree, - screen, - con.launch_args.no_style, - ))) - } -} |