• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pomsky-lang / pomsky / 6421156176

05 Oct 2023 03:27PM UTC coverage: 80.191% (-0.1%) from 80.315%
6421156176

push

github

Aloso
chore: update deps, fix new lints

25 of 25 new or added lines in 6 files covered. (100.0%)

3267 of 4074 relevant lines covered (80.19%)

246.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.63
/pomsky-bin/src/main.rs
1
use std::{io, io::Write as _, process::exit, time::Instant};
1✔
2

3
use pomsky::{
4
    diagnose::{Diagnostic, Severity},
5
    options::{CompileOptions, RegexFlavor},
6
    Expr,
7
};
8

9
#[macro_use]
10
mod format;
11
mod args;
12
mod result;
13

14
use args::{Args, DiagnosticSet, Input};
15
use result::CompilationResult;
16

17
pub fn main() {
33✔
18
    let args = match args::parse_args() {
33✔
19
        Ok(args) => args,
25✔
20
        Err(error) => {
8✔
21
            print_diagnostic(
8✔
22
                &Diagnostic::ad_hoc(Severity::Error, None, error.to_string(), None),
8✔
23
                None,
8✔
24
            );
8✔
25
            args::print_short_usage_and_help_err();
8✔
26
            exit(2)
8✔
27
        }
28
    };
29

30
    if args.json && std::env::var_os("NO_COLOR").is_none() {
25✔
31
        std::env::set_var("NO_COLOR", "1");
3✔
32
    }
33

34
    match &args.input {
25✔
35
        Input::Value(input) => compile(input, &args),
19✔
36
        Input::File(path) => match std::fs::read_to_string(path) {
6✔
37
            Ok(input) => compile(&input, &args),
3✔
38
            Err(error) => {
3✔
39
                print_diagnostic(
3✔
40
                    &Diagnostic::ad_hoc(Severity::Error, None, error.to_string(), None),
3✔
41
                    None,
3✔
42
                );
3✔
43
                exit(3);
3✔
44
            }
45
        },
46
    }
47
}
22✔
48

49
fn compile(input: &str, args: &Args) {
22✔
50
    let start = Instant::now();
22✔
51

52
    let options = CompileOptions {
22✔
53
        flavor: args.flavor.unwrap_or(RegexFlavor::Pcre),
22✔
54
        max_range_size: 12,
55
        allowed_features: args.allowed_features,
22✔
56
    };
57

58
    let (parsed, warnings) = match Expr::parse(input) {
22✔
59
        (Some(res), warnings) => (res, warnings),
21✔
60
        (None, err) => {
1✔
61
            print_parse_errors(err, Some(input), start.elapsed().as_micros(), args.json);
1✔
62
            exit(1);
1✔
63
        }
64
    };
65
    let mut warnings = warnings.collect::<Vec<_>>();
21✔
66

67
    if args.debug {
21✔
68
        eprintln!("======================== debug ========================");
1✔
69
        eprintln!("{parsed:#?}\n");
1✔
70
    }
71

72
    if !args.json {
21✔
73
        print_warnings(&warnings, args, Some(input));
19✔
74
    }
75

76
    let compiled = match parsed.compile(input, options) {
21✔
77
        (Some(res), compile_warnings) => {
20✔
78
            if args.json {
20✔
79
                warnings.extend(compile_warnings);
2✔
80
            } else {
81
                print_warnings(&compile_warnings, args, Some(input));
18✔
82
            }
83

84
            res
20✔
85
        }
20✔
86
        (None, errors) => {
1✔
87
            if args.json {
1✔
88
                CompilationResult::error(start.elapsed().as_micros())
×
89
                    .with_diagnostics(errors, Some(input))
×
90
                    .with_diagnostics(
91
                        warnings.into_iter().filter_map(|w| {
×
92
                            if args.warnings.is_enabled(w.kind) {
×
93
                                Some(w)
×
94
                            } else {
95
                                None
×
96
                            }
97
                        }),
×
98
                        Some(input),
×
99
                    )
100
                    .output_json();
×
101
            } else {
102
                for err in &errors {
2✔
103
                    print_diagnostic(err, Some(input));
1✔
104
                }
105
            }
106
            std::process::exit(1);
1✔
107
        }
108
    };
109

110
    if args.json {
20✔
111
        CompilationResult::success(compiled, start.elapsed().as_micros())
4✔
112
            .with_diagnostics(
113
                warnings.into_iter().filter_map(|w| {
4✔
114
                    if args.warnings.is_enabled(w.kind) {
2✔
115
                        Some(w)
2✔
116
                    } else {
117
                        None
×
118
                    }
119
                }),
2✔
120
                Some(input),
2✔
121
            )
122
            .output_json();
2✔
123
    } else if args.no_new_line {
18✔
124
        print!("{compiled}");
3✔
125
        io::stdout().flush().unwrap();
3✔
126
    } else {
127
        println!("{compiled}");
15✔
128
    }
129
}
20✔
130

131
fn print_parse_errors(
1✔
132
    mut diagnostics: impl Iterator<Item = Diagnostic>,
133
    source_code: Option<&str>,
134
    time: u128,
135
    json: bool,
136
) {
137
    if json {
1✔
138
        CompilationResult::error(time).with_diagnostics(diagnostics, source_code).output_json();
1✔
139
    } else {
140
        let mut len = 0;
×
141
        for d in (&mut diagnostics).take(8) {
×
142
            len += 1;
×
143
            print_diagnostic(&d, source_code);
×
144
        }
×
145

146
        len += diagnostics.count();
×
147

148
        if len > 8 {
×
149
            efprintln!(C!"note" ": some errors were omitted");
×
150
        }
151

152
        if len > 1 {
×
153
            let len = &len.to_string();
×
154
            efprintln!(R!"error" ": could not compile expression due to " {len} " previous errors");
×
155
        } else {
×
156
            efprintln!(R!"error" ": could not compile expression due to previous error");
×
157
        }
158
    }
159
}
1✔
160

161
fn print_warnings(warnings: &[Diagnostic], args: &Args, source_code: Option<&str>) {
37✔
162
    if matches!(&args.warnings, DiagnosticSet::Enabled(set) if set.is_empty()) {
39✔
163
        return;
164
    }
165

166
    let mut len = 0;
35✔
167

168
    for diagnostic in warnings {
37✔
169
        if args.warnings.is_enabled(diagnostic.kind) {
2✔
170
            len += 1;
1✔
171
            match len {
×
172
                1..=8 => print_diagnostic(diagnostic, source_code),
1✔
173
                9 => efprintln!(C!"note" ": some warnings were omitted"),
×
174
                _ => {}
175
            }
176
        }
177
    }
178

179
    if len > 1 {
35✔
180
        let len = len.to_string();
×
181
        efprintln!(Y!"warning" ": pomsky generated " {&len} " warnings");
×
182
    }
×
183
}
37✔
184

185
fn print_diagnostic(diagnostic: &Diagnostic, source_code: Option<&str>) {
13✔
186
    let kind = diagnostic.kind.to_string();
13✔
187
    let display = diagnostic.default_display(source_code).to_string();
13✔
188
    if let Some(code) = diagnostic.code {
13✔
189
        let code = code.to_string();
2✔
190
        match diagnostic.severity {
2✔
191
            Severity::Error => efprint!(R!"error " R!{&code} {&kind} ":\n" {&display}),
1✔
192
            Severity::Warning => efprint!(Y!"warning " Y!{&code} {&kind} ":\n" {&display}),
1✔
193
        }
194
    } else {
2✔
195
        match diagnostic.severity {
11✔
196
            Severity::Error => efprint!(R!"error" {&kind} ":\n" {&display}),
11✔
197
            Severity::Warning => efprint!(Y!"warning" {&kind} ":\n" {&display}),
×
198
        }
199
    }
200
}
13✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc