taro_cli/
lib.rs

1//! Wrapper for multiple quality of life command-line tools.
2//! 
3//! Includes:
4//! - [find]
5//! - [gitignore]
6//! - [grep]
7
8use std::{ str, vec };
9use std::{ env, path::Path };
10
11mod modules;
12pub use crate::modules::grep;
13pub use crate::modules::find;
14pub use crate::modules::gitignore;
15
16/// Possible functions that can be run using the command line interface.
17pub enum Functions {
18  Grep,
19  Find,
20  GitIgnore
21}
22
23pub struct Config {
24  pub function: Functions
25}
26
27impl Config {
28  pub fn new(args: &[String]) -> Result<Config, &'static str> {
29    if args.len() < 2 {
30      return Err("not enough arguments");
31    }
32
33    match args[1].as_str() {
34      "grep" => Ok(Config { function: Functions::Grep }),
35      "find" => Ok(Config { function: Functions::Find }),
36      "gitignore" => Ok(Config { function: Functions::GitIgnore }),
37      _ => Err("unknown function")
38    }
39  }
40}
41
42/// Required configuration for [grep].
43pub struct GrepConfig {
44  /// Substring to query for.
45  pub query: String,
46  /// Path of the file to query.
47  pub file_path: String,
48  /// Ignore-case flag.
49  pub ignore_case: bool,
50}
51
52impl GrepConfig {
53  /// Builds the [GrepConfig] from command-line arguments
54  pub fn build(args: &[String]) -> Result<GrepConfig, &'static str> {
55    if args.len() < 4 {
56      return Err("not enough argument for grep");
57    }
58
59    let query = args[2].clone();
60    let file_path = args[3].clone();
61
62    let ignore_case = env::var("IGNORE_CASE").is_ok();
63
64    Ok(GrepConfig { query, file_path, ignore_case })
65  }
66}
67
68/// Required configuration for [find].
69pub struct FindConfig<'a> {
70  /// Path of the folder to start the search.
71  pub path: &'a Path,
72  /// Substring to query for.
73  pub query: String,
74  /// Folder depth value for the serach.
75  pub depth: usize,
76}
77
78impl<'a> FindConfig<'a> {
79  /// Builds the [FindConfig] from command-line arguments
80  pub fn build(args: &[String]) -> Result<FindConfig, &'static str> {
81    if args.len() < 4 {
82      return Err("not enough argument for find");
83    }
84
85    let path = Path::new(args[2].as_str());
86    let query = args[3].clone();
87
88    let depth = match env::var("DEPTH") {
89      Ok(depth) => depth.parse().unwrap_or_else(|_| {
90        eprintln!("Cannot parse depth \"{}\" as an integer, using default value (10)", depth); 
91        10
92      }),
93      Err(_) => {
94        println!("Using default depth value (10)");
95        10
96      }
97    };
98
99    Ok(FindConfig { path, query, depth })
100  }
101}
102
103/// Required configuration for [gitignore].
104pub struct GitIgnoreConfig {
105  /// Operating Systems, IDEs, Languages to include in the gitignore.
106  pub include: Vec<String>,
107  /// Optional output path to save the generated gitignore.
108  pub output: Option<String>,
109}
110
111impl GitIgnoreConfig {
112  /// Builds the [GitIgnoreConfig] from command-line arguments
113  pub fn build(args: &[String]) -> Result<GitIgnoreConfig, &'static str> {
114    if args.len() < 3 {
115      return Err("not enough argument for gitignore");
116    }
117
118    let mut include = vec![String::new(); args.len() - 2];
119
120    for (i, item) in args.iter().skip(2).enumerate() {
121      include[i] = item.clone();
122    }
123
124    let output = env::var("OUTPUT").ok();
125
126    Ok(GitIgnoreConfig { include, output })
127  }
128}