1+ use std:: io:: { BufWriter , Write } ;
2+
13use anyhow:: { bail, Result } ;
24use clap:: Parser ;
35use fs_err as fs;
46use rustdoc_json_types:: { Crate , Id , FORMAT_VERSION } ;
7+ use serde:: Serialize ;
58use serde_json:: Value ;
69
710pub ( crate ) mod item_kind;
811mod json_find;
912mod validator;
1013
11- #[ derive( Debug , PartialEq , Eq ) ]
14+ #[ derive( Debug , PartialEq , Eq , Serialize , Clone ) ]
1215struct Error {
1316 kind : ErrorKind ,
1417 id : Id ,
1518}
1619
17- #[ derive( Debug , PartialEq , Eq ) ]
20+ #[ derive( Debug , PartialEq , Eq , Serialize , Clone ) ]
1821enum ErrorKind {
1922 NotFound ( Vec < json_find:: Selector > ) ,
2023 Custom ( String ) ,
2124}
2225
26+ #[ derive( Debug , Serialize ) ]
27+ struct JsonOutput {
28+ path : String ,
29+ errors : Vec < Error > ,
30+ }
31+
2332#[ derive( Parser ) ]
2433struct Cli {
2534 /// The path to the json file to be linted
@@ -28,10 +37,13 @@ struct Cli {
2837 /// Show verbose output
2938 #[ arg( long) ]
3039 verbose : bool ,
40+
41+ #[ arg( long) ]
42+ json_output : Option < String > ,
3143}
3244
3345fn main ( ) -> Result < ( ) > {
34- let Cli { path, verbose } = Cli :: parse ( ) ;
46+ let Cli { path, verbose, json_output } = Cli :: parse ( ) ;
3547
3648 let contents = fs:: read_to_string ( & path) ?;
3749 let krate: Crate = serde_json:: from_str ( & contents) ?;
@@ -42,6 +54,13 @@ fn main() -> Result<()> {
4254 let mut validator = validator:: Validator :: new ( & krate, krate_json) ;
4355 validator. check_crate ( ) ;
4456
57+ if let Some ( json_output) = json_output {
58+ let output = JsonOutput { path : path. clone ( ) , errors : validator. errs . clone ( ) } ;
59+ let mut f = BufWriter :: new ( fs:: File :: create ( json_output) ?) ;
60+ serde_json:: to_writer ( & mut f, & output) ?;
61+ f. flush ( ) ?;
62+ }
63+
4564 if !validator. errs . is_empty ( ) {
4665 for err in validator. errs {
4766 match err. kind {
0 commit comments