liboskar/
cli_helpers.rs

1use clap::Values;
2use colored::*;
3use error::*;
4use nom::IResult;
5use regex::Regex;
6use std::path::PathBuf;
7use std::process::exit;
8use utils::get_processors;
9
10/// Parse a string into a regular expression for the 'artifacts' subcommand. Adds ignores for
11/// typical version control directories if none are present.
12pub fn get_excludes(cli_excludes: Option<&str>) -> Regex {
13    match cli_excludes {
14        Some(s) => {
15            let mut x = "(".to_string();
16            x.push_str(s);
17            x.push_str(r")|(\.git|\.pijul|_darcs|\.hg|\.gnupg)$");
18            check_regex(&x)
19        }
20        _ => Regex::new(r"(\.git|\.pijul|_darcs|\.hg|\.gnupg)$").unwrap(), // ok because static
21    }
22}
23
24pub fn get_depth(depth_from_cli: Option<&str>) -> u8 {
25    if let Some(n) = depth_from_cli {
26        if let Ok(n) = n.parse::<u8>() {
27            n
28        } else {
29            eprintln!("{}", Internal::ParseNum);
30            exit(0x0f01);
31        }
32    } else {
33        2
34    }
35}
36
37pub fn get_num(num_from_cli: Option<&str>) -> usize {
38    if let Some(num) = num_from_cli {
39        if let Ok(n) = num.parse::<usize>() {
40            n
41        } else {
42            eprintln!("{}", Internal::ParseNum);
43            exit(0x0f01);
44        }
45    } else {
46        8
47    }
48}
49
50/// If the user has supplied a string, parse it, otherwise, read the number of processors.
51pub fn get_threads(num_from_cli: Option<&str>) -> usize {
52    match num_from_cli {
53        Some(num) => {
54            if let Ok(n) = num.parse::<usize>() {
55                n
56            } else {
57                eprintln!("{}", Internal::ParseNum);
58                exit(0x0f01);
59            }
60        }
61        _ => get_processors(),
62    }
63}
64
65pub fn get_dirs(paths_from_cli: Option<Values>) -> Vec<PathBuf> {
66    if let Some(read) = paths_from_cli {
67        read.map(PathBuf::from).collect()
68    } else {
69        let mut v = Vec::new();
70        v.push(PathBuf::from("."));
71        v
72    }
73}
74
75pub fn get_dir(path_from_cli: Option<&str>) -> PathBuf {
76    match path_from_cli {
77        Some(read) => PathBuf::from(read),
78        _ => PathBuf::from("."),
79    }
80}
81
82/// Parse a threshold from a command-line flag.
83///
84/// # Examples
85///
86/// ```
87/// use liboskar::prelude::*;
88///
89/// let threshold_string = Some("31M");
90/// assert_eq!(threshold(threshold_string), Some(32505856))
91/// ```
92pub fn threshold(s: Option<&str>) -> Option<u64> {
93    s.map(pre_threshold)
94}
95
96fn pre_threshold(t_from_cli: &str) -> u64 {
97    match get_threshold(t_from_cli.as_bytes()) {
98        IResult::Done(_, n) => n,
99        _ => {
100            eprintln!(
101                "{}: failed to parse threshold. defaulting to 1M",
102                "Warning".yellow()
103            );
104            1048576 // 1 MB
105        }
106    }
107}
108
109fn to_u64(nums: Vec<char>, size_tag: &[u8]) -> u64 {
110    let pre: String = nums.into_iter().collect();
111    let n = if let Ok(n) = pre.parse::<u64>() {
112        n
113    } else {
114        eprintln!("{}", Internal::ParseNum);
115        exit(0x0f01);
116    };
117
118    match size_tag {
119        b"G" | b"g" => n * 1073741824,
120        b"M" | b"m" => n * 1048576,
121        b"k" | b"K" => n * 1024,
122        b"b" | b"B" => n,
123        _ => exit(0x0f01),
124    }
125}
126
127named!(digit_char<&[u8], char>,
128    alt!(
129        char!('1') |
130        char!('2') |
131        char!('3') |
132        char!('4') |
133        char!('5') |
134        char!('6') |
135        char!('7') |
136        char!('8') |
137        char!('9') |
138        char!('0')
139    )
140);
141
142named!(get_threshold<&[u8],u64>,
143    do_parse!(
144        nums:     many1!(digit_char) >>
145        size_tag: alt!(tag!("M") |
146                       tag!("G") |
147                       tag!("k") |
148                       tag!("b") |
149                       tag!("B") |
150                       tag!("K") |
151                       tag!("g") |
152                       tag!("m")) >>
153        (to_u64(nums, size_tag))
154    )
155);