@@ -10,10 +10,11 @@ use std::sync::Mutex;
1010use clap:: Args ;
1111use contracts:: requires;
1212use kdl:: { KdlDocument , KdlNode } ;
13- use miette:: { IntoDiagnostic , SourceSpan } ;
13+ use miette:: { IntoDiagnostic , LabeledSpan , NamedSource , SourceOffset , SourceSpan } ;
1414use strum:: EnumIs ;
1515use thiserror:: Error ;
1616
17+ use usage:: parse:: config:: SpecConfig ;
1718use usage:: { SchemaCmd , Spec } ;
1819use xx:: { context, file} ;
1920
@@ -52,10 +53,7 @@ impl Markdown {
5253 fn inject_file ( & self , inject : & Path ) -> miette:: Result < ( ) > {
5354 let raw = file:: read_to_string ( inject) . into_diagnostic ( ) ?;
5455 context:: set_load_root ( inject. parent ( ) . unwrap ( ) . to_path_buf ( ) ) ;
55- let out = raw
56- . lines ( )
57- . map ( |line| line. parse ( ) )
58- . collect :: < miette:: Result < Vec < UsageMdDirective > > > ( ) ?
56+ let out = parse_readme_directives ( inject, & raw ) ?
5957 . into_iter ( )
6058 . try_fold ( UsageMdContext :: new ( ) , |ctx, d| d. run ( ctx) ) ?
6159 . out
@@ -159,6 +157,7 @@ enum UsageMdDirective {
159157 GlobalFlags ,
160158 CommandIndex ,
161159 Commands ,
160+ Config ,
162161 EndToken ,
163162 Plain ( String ) ,
164163}
@@ -175,6 +174,7 @@ impl Display for UsageMdDirective {
175174 UsageMdDirective :: GlobalFlags => write ! ( f, "<!-- [USAGE] global_flags -->" ) ,
176175 UsageMdDirective :: CommandIndex => write ! ( f, "<!-- [USAGE] command_index -->" ) ,
177176 UsageMdDirective :: Commands => write ! ( f, "<!-- [USAGE] commands -->" ) ,
177+ UsageMdDirective :: Config => write ! ( f, "<!-- [USAGE] config -->" ) ,
178178 UsageMdDirective :: EndToken => write ! ( f, "<!-- [USAGE] -->" ) ,
179179 UsageMdDirective :: Plain ( line) => write ! ( f, "{}" , line) ,
180180 }
@@ -291,6 +291,13 @@ impl UsageMdDirective {
291291 print_commands ( & ctx, & [ & spec. cmd ] ) ?;
292292 ctx. push ( format ! ( "<!-- [USAGE] -->" ) ) ;
293293 }
294+ UsageMdDirective :: Config => {
295+ ctx. plain = false ;
296+ let spec = ctx. spec . as_ref ( ) . unwrap ( ) ;
297+ ctx. push ( self . to_string ( ) ) ;
298+ print_config ( & ctx, & spec. config ) ?;
299+ ctx. push ( format ! ( "<!-- [USAGE] -->" ) ) ;
300+ }
294301 UsageMdDirective :: EndToken => {
295302 ctx. plain = true ;
296303 }
@@ -354,6 +361,26 @@ fn print_commands(ctx: &UsageMdContext, cmds: &[&SchemaCmd]) -> miette::Result<(
354361 Ok ( ( ) )
355362}
356363
364+ fn print_config ( ctx : & UsageMdContext , config : & SpecConfig ) -> miette:: Result < ( ) > {
365+ for ( key, prop) in & config. props {
366+ ctx. push ( format ! ( "### `{key}`" , key = key) ) ;
367+ if let Some ( env) = & prop. env {
368+ ctx. push ( format ! ( "env: `{env}`" , env = env) ) ;
369+ }
370+ if !prop. default . is_null ( ) {
371+ ctx. push ( format ! ( "default: `{default}`" , default = prop. default ) ) ;
372+ }
373+ if let Some ( help) = & prop. help {
374+ ctx. push ( format ! ( "{help}" , help = help) ) ;
375+ }
376+ if let Some ( long_help) = & prop. long_help {
377+ ctx. push ( format ! ( "{long_help}" , long_help = long_help) ) ;
378+ }
379+ ctx. push ( "Used by commnds: global|*" . to_string ( ) ) ;
380+ }
381+ Ok ( ( ) )
382+ }
383+
357384#[ derive( Error , Diagnostic , Debug ) ]
358385#[ error( "Error parsing markdown directive" ) ]
359386#[ diagnostic( ) ]
@@ -367,11 +394,12 @@ struct MarkdownError {
367394 err_span : SourceSpan ,
368395}
369396
370- impl FromStr for UsageMdDirective {
371- type Err = miette :: Error ;
372- fn from_str ( line : & str ) -> Result < Self , Self :: Err > {
397+ fn parse_readme_directives ( path : & Path , full : & str ) -> miette :: Result < Vec < UsageMdDirective > > {
398+ let mut directives = vec ! [ ] ;
399+ for ( line_num , line ) in full . lines ( ) . enumerate ( ) {
373400 if line == "<!-- [USAGE] -->" {
374- return Ok ( UsageMdDirective :: EndToken ) ;
401+ directives. push ( UsageMdDirective :: EndToken ) ;
402+ continue ;
375403 }
376404 let directive = if let Some ( x) = regex ! ( r#"<!-- \[USAGE\] (.*) -->"# ) . captures ( line) {
377405 let doc: KdlDocument = x. get ( 1 ) . unwrap ( ) . as_str ( ) . parse ( ) ?;
@@ -400,13 +428,28 @@ impl FromStr for UsageMdDirective {
400428 "usage_overview" => UsageMdDirective :: UsageOverview ,
401429 "global_args" => UsageMdDirective :: GlobalArgs ,
402430 "global_flags" => UsageMdDirective :: GlobalFlags ,
431+ //"config" => UsageMdDirective::Config,
403432 "command_index" => UsageMdDirective :: CommandIndex ,
404433 "commands" => UsageMdDirective :: Commands ,
405- _ => Err ( err ( "unknown directive type" . into ( ) , * node. name ( ) . span ( ) ) ) ?,
434+ // k => Err(err("unknown directive type".into(), *node.name().span()))?,
435+ // k => diagnostic!(source_code=doc.to_string(),
436+ // source_code= "unknown directive type".into(),
437+ // // err_span= *node.name().span()
438+ // }),
439+ k => Err ( miette ! (
440+ labels = vec![ LabeledSpan :: new(
441+ Some ( format!( "unknown directive type: {k}" ) ) ,
442+ SourceOffset :: from_location( full, line_num + 1 , 14 ) . offset( ) ,
443+ node. name( ) . span( ) . len( ) ,
444+ ) ] ,
445+ "Error parsing markdown directive" ,
446+ )
447+ . with_source_code ( NamedSource :: new ( path. to_string_lossy ( ) , full. to_string ( ) ) ) ) ?,
406448 }
407449 } else {
408450 UsageMdDirective :: Plain ( line. into ( ) )
409451 } ;
410- Ok ( directive)
452+ directives . push ( directive) ;
411453 }
454+ Ok ( directives)
412455}
0 commit comments