lncat/
lib.rs

1//! # Utils used to create a `cat` like command
2//!  
3//! Here I implemented a `Config` struct to set the configs and
4//! a function called `run` to consume that struct.
5
6
7use std::path::Path;
8use std::io::{self, BufRead};
9use std::fs::File;
10use std::error::Error;
11
12/// This struct contains all file paths to be concatenated
13///
14/// # Example
15///
16/// ```
17/// use lncat::Config;
18/// use std::env;
19/// 
20/// let config_result: Result<Config, String> = Config::from(env::args());
21/// ```
22
23pub struct Config {
24    pub paths: Vec<String>,
25}
26
27impl Config {
28
29    /// Accepts an iterator of type String and returns a `Result<Config, String>`
30    /// 
31    /// The function below helps to create a config struct that will contain all
32    /// the file path's. if there is an invalid file path like a directory or
33    /// a complete invalid piece of text it will return a String error.
34    /// 
35    /// # Example
36    /// 
37    /// ```
38    /// use lncat::Config;
39    /// use std::env;
40    /// 
41    /// let config_result: Result<Config, String> = Config::from(env::args());
42    /// ```
43    pub fn from(mut paths: impl Iterator<Item=String>) -> Result<Config, String> {
44
45        // Ignore the first element
46        paths.next();
47
48        let mut result_paths: Vec<String> = Vec::new();
49        for path in paths {
50
51            let std_path = Path::new(&path);
52
53            if std_path.is_file() {
54                result_paths.push(path)
55            } else if std_path.is_dir() {
56                return Err(format!("`{}` is a directory", path))
57            } else {
58                return Err(format!("`{}` is an invalid input", path))
59            }
60        }
61
62        Ok(Config {
63            paths: result_paths,
64        })
65    }
66}
67
68/// The function `run` takes a `Config` as the input and concatenates all the files in it
69/// 
70/// # Example
71/// ```
72/// use lncat::Config;
73/// use std::env;
74/// 
75/// let config_result = Config::from(env::args());
76/// match config_result {
77///     Ok(config) => {
78///         lncat::run(config).expect("There was a problem reading file.");
79///         },
80///     Err(err) => {
81///         eprintln!("{}", err);
82///         }
83/// }
84/// ```
85
86pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
87    for path in config.paths {
88        let file = File::open(path)?;
89        let reader = io::BufReader::new(file);
90
91        for line in reader.lines() {
92            println!("{}", line?);
93        }
94
95    }
96
97    Ok(())
98}