11use crate :: ast_description:: { parse_description_and_continue, DescriptionAndNext } ;
2+ use crate :: ast_directive:: parse_directive;
23use crate :: ast_identifier:: { parse_identifier, Identifier } ;
34use crate :: parser:: Rule ;
45use crate :: utils:: { unknown_rule_error, OwnedSpan } ;
6+ use crate :: Directive ;
57use pest:: iterators:: Pair ;
68
79#[ derive( Debug , Clone , PartialEq , Default ) ]
810pub struct Schema {
911 pub span : OwnedSpan ,
1012 pub description : String ,
11- // TODO: add directives
13+ pub directives : Vec < Directive > ,
1214 pub query : Identifier ,
1315 pub mutation : Identifier ,
1416 pub subscription : Identifier ,
@@ -38,6 +40,11 @@ impl Schema {
3840 self . description = description. to_string ( ) ;
3941 self . clone ( )
4042 }
43+
44+ pub fn directive ( & mut self , directive : Directive ) -> Self {
45+ self . directives . push ( directive) ;
46+ self . clone ( )
47+ }
4148}
4249
4350enum SchemaKey {
@@ -68,11 +75,16 @@ pub(crate) fn parse_schema(
6875 Rule :: schema_def => {
6976 let span = OwnedSpan :: from ( pair. as_span ( ) , file) ;
7077 let mut childs = pair. into_inner ( ) ;
71- let DescriptionAndNext ( description, next) =
78+ let DescriptionAndNext ( description, mut next) =
7279 parse_description_and_continue ( & mut childs, file) ;
7380 let mut query = Identifier :: from ( "" ) ;
7481 let mut mutation = Identifier :: from ( "" ) ;
7582 let mut subscription = Identifier :: from ( "" ) ;
83+ let mut directives = vec ! [ ] ;
84+ while let Rule :: directive = next. as_rule ( ) {
85+ directives. push ( parse_directive ( next, file) ?) ;
86+ next = childs. next ( ) . unwrap ( ) ;
87+ }
7688 for field in next. into_inner ( ) {
7789 let mut field_parts = field. into_inner ( ) ;
7890 let key = parse_schema_key ( field_parts. next ( ) . unwrap ( ) , file) ?;
@@ -85,6 +97,7 @@ pub(crate) fn parse_schema(
8597 }
8698 Ok ( Schema {
8799 span,
100+ directives,
88101 description,
89102 query,
90103 mutation,
@@ -112,6 +125,27 @@ mod tests {
112125 )
113126 }
114127
128+ #[ test]
129+ fn test_accepts_directive ( ) {
130+ assert_eq ! (
131+ parse_input( "schema @dir { query: Query }" ) ,
132+ Ok ( Schema :: build( )
133+ . query( "Query" )
134+ . directive( Directive :: build( "dir" ) ) )
135+ )
136+ }
137+
138+ #[ test]
139+ fn test_accepts_two_directives ( ) {
140+ assert_eq ! (
141+ parse_input( "schema @dir1 @dir2 { query: Query }" ) ,
142+ Ok ( Schema :: build( )
143+ . query( "Query" )
144+ . directive( Directive :: build( "dir1" ) )
145+ . directive( Directive :: build( "dir2" ) ) )
146+ )
147+ }
148+
115149 #[ test]
116150 fn test_parses_query_with_description ( ) {
117151 assert_eq ! (
0 commit comments