1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#[macro_use]
extern crate lazy_static;
extern crate isatty;
extern crate json_highlight_writer;
extern crate regex;

pub mod input;
mod selection;

pub fn json_grep(config: input::Config) -> Result<(), Option<String>> {
    let matched_filters: Result<Vec<_>, String> = config
        .matchers
        .iter()
        .map(|pattern| input::in_configured_case(pattern, &config))
        .map(|pattern| selection::match_filters(&pattern))
        .collect();

    let matched_filters = matched_filters?;

    let has_matched = input::match_input(
        &config,
        &|line| {
            invert_result(
                config.invert_match,
                input::match_line(&matched_filters, &config, line),
            )
        },
        &|(index, matched_count, matched_result)| {
            if let Ok(matched_line) = matched_result {
                if !(config.print_only_count || config.is_quiet_mode) {
                    println!(
                        "{}{}",
                        index
                            .map(|index| index.to_string() + ":")
                            .unwrap_or(String::from("")),
                        matched_line
                    );
                };
            };
            (index, matched_count)
        },
    );

    match has_matched {
        Ok(match_count) => {
            if config.print_only_count {
                println!("{}", match_count.expect("failed to count matched input"));
            }
            Ok(())
        }
        Err(err) => Err(err),
    }
}

pub fn invert_result<A>(should_invert: bool, result: Result<A, A>) -> Result<A, A> {
    match result {
        Ok(ok_res) => {
            if should_invert {
                Err(ok_res)
            } else {
                Ok(ok_res)
            }
        }
        Err(err_res) => {
            if should_invert {
                Ok(err_res)
            } else {
                Err(err_res)
            }
        }
    }
}