@@ -21,11 +21,16 @@ use serde::Deserialize;
2121pub trait MdtestConfig : Clone + Default + for < ' de > Deserialize < ' de > { }
2222
2323/// Parse the Markdown `source` as a test suite with given `title`.
24+ ///
25+ /// `validate_config` is invoked once for every literally-declared `toml` config block
26+ /// (after deserialization, before it replaces the section's inherited config) so callers
27+ /// can enforce invariants that mdtest itself shouldn't know about.
2428pub fn parse < ' s , C : MdtestConfig > (
2529 title : & ' s str ,
2630 source : & ' s str ,
31+ validate_config : impl FnMut ( & C ) -> anyhow:: Result < ( ) > ,
2732) -> anyhow:: Result < MarkdownTestSuite < ' s , C > > {
28- let parser = Parser :: new ( title, source) ;
33+ let parser = Parser :: new ( title, source, validate_config ) ;
2934 parser. parse ( )
3035}
3136
@@ -480,8 +485,7 @@ impl SectionStack {
480485}
481486
482487/// Parse the source of a Markdown file into a [`MarkdownTestSuite`].
483- #[ derive( Debug ) ]
484- struct Parser < ' s , C > {
488+ struct Parser < ' s , C , F > {
485489 /// [`Section`]s of the final [`MarkdownTestSuite`].
486490 sections : IndexVec < SectionId , Section < ' s , C > > ,
487491
@@ -507,10 +511,13 @@ struct Parser<'s, C> {
507511
508512 /// Whether or not the current section has a config block.
509513 current_section_has_config : bool ,
514+
515+ /// Callback to validate config blocks
516+ validate_config : F ,
510517}
511518
512- impl < ' s , C : MdtestConfig > Parser < ' s , C > {
513- fn new ( title : & ' s str , source : & ' s str ) -> Self {
519+ impl < ' s , C : MdtestConfig , F : FnMut ( & C ) -> anyhow :: Result < ( ) > > Parser < ' s , C , F > {
520+ fn new ( title : & ' s str , source : & ' s str , validate_config : F ) -> Self {
514521 let mut sections = IndexVec :: default ( ) ;
515522 let root_section_id = sections. push ( Section {
516523 title,
@@ -529,6 +536,7 @@ impl<'s, C: MdtestConfig> Parser<'s, C> {
529536 stack : SectionStack :: new ( root_section_id) ,
530537 current_section_files : IndexMap :: default ( ) ,
531538 current_section_has_config : false ,
539+ validate_config,
532540 }
533541 }
534542
@@ -912,6 +920,8 @@ impl<'s, C: MdtestConfig> Parser<'s, C> {
912920
913921 let config: C = toml:: from_str ( code) . context ( "Error while parsing Markdown TOML config" ) ?;
914922
923+ ( self . validate_config ) ( & config) ?;
924+
915925 let current_section = & mut self . sections [ self . stack . top ( ) ] ;
916926 current_section. config = config;
917927
@@ -1107,7 +1117,7 @@ mod tests {
11071117 title : & ' s str ,
11081118 source : & ' s str ,
11091119 ) -> anyhow:: Result < super :: MarkdownTestSuite < ' s , TestConfig > > {
1110- super :: parse :: < TestConfig > ( title, source)
1120+ super :: parse :: < TestConfig > ( title, source, |_| Ok ( ( ) ) )
11111121 }
11121122
11131123 #[ test]
0 commit comments