1+ use std:: error:: Error ;
2+ use clap:: { Arg , ArgAction , Command } ;
3+ use std:: fs:: File ;
4+ use std:: io:: { self , stdin, BufRead , BufReader } ;
5+
6+ #[ allow( unused) ]
7+ #[ derive( Debug ) ]
8+ pub struct Config {
9+ files : Vec < String > ,
10+ number_lines : bool ,
11+ number_nonblank_lines : bool ,
12+ }
13+
14+ type MyResult < T > = Result < T , Box < dyn Error > > ;
15+
16+ fn open ( filename : & str ) -> MyResult < Box < dyn BufRead > > {
17+ match filename {
18+ "-" => Ok ( Box :: new ( BufReader :: new ( io:: stdin ( ) ) ) ) ,
19+ _ => Ok ( Box :: new ( BufReader :: new ( File :: open ( filename) ?) ) ) ,
20+ }
21+ }
22+
23+ pub fn run ( config : Config ) -> MyResult < ( ) > {
24+ // dbg!(config);
25+ for filename in config. files {
26+ // println!("{}", filename);
27+ match open ( & filename) {
28+ Err ( err) => eprintln ! ( "Failed to open {}: {}" , filename, err) ,
29+ Ok ( _) => println ! ( "Opened {}" , filename) ,
30+ }
31+ }
32+ Ok ( ( ) )
33+ }
34+
35+ pub fn get_args ( ) -> MyResult < Config > {
36+ let matches = Command :: new ( "ch03_catr" )
37+ . version ( "0.1.0" )
38+ . author ( "Rakuram <[email protected] >" ) 39+ . about ( "Rust cat Command" )
40+ . help_template (
41+ "{name} {version} \n \
42+ {author} \n \
43+ {about} \n \n \
44+ USAGE: \n {usage}\n \n \
45+ {all-args}" ,
46+ )
47+ . arg (
48+ Arg :: new ( "files" )
49+ . value_name ( "FILE" )
50+ . help ( "Input files" )
51+ // .required(true) // reason why required is not used is because we are using default value
52+ . num_args ( 1 ..)
53+ . default_value ( "-" )
54+ . action ( ArgAction :: Append ) ,
55+ )
56+ . arg (
57+ Arg :: new ( "number_lines" )
58+ . short ( 'n' )
59+ . long ( "number" )
60+ . help ( "number all output lines" )
61+ . action ( ArgAction :: SetTrue )
62+ . conflicts_with ( "number_nonblank" ) ,
63+ )
64+ . arg (
65+ Arg :: new ( "number_nonblank" )
66+ . short ( 'b' )
67+ . long ( "number-nonblank" )
68+ . help ( "number nonempty output lines, overrides -n" )
69+ . action ( ArgAction :: SetTrue ) ,
70+ )
71+ . get_matches ( ) ;
72+
73+ // let text: Vec<String> = matches
74+ // .get_many("files")
75+ // .expect("filename is required")
76+ // .cloned()
77+ // .collect();
78+
79+ // println!("{:#?}", text);
80+
81+ // let number_lines = matches.get_flag("number_lines");
82+
83+ // let number_nonblank_lines = matches.get_flag("number_nonblank_lines");
84+
85+ // println!("text: {:#?}", text);
86+ // println!("number_lines: {:#?}", number_lines);
87+ // println!("number_nonblank_lines: {:#?}", number_nonblank_lines);
88+
89+ Ok ( Config {
90+ files : matches. get_many ( "files" ) . unwrap ( ) . cloned ( ) . collect ( ) ,
91+ number_lines : matches. get_flag ( "number_lines" ) ,
92+ number_nonblank_lines : matches. get_flag ( "number_nonblank" ) ,
93+ } )
94+ }
0 commit comments