@@ -3,6 +3,7 @@ use std::ptr;
33use arcstr:: ArcStr ;
44use derive_more:: with_trait:: Display ;
55use fnv:: FnvHashMap ;
6+
67#[ cfg( feature = "schema-language" ) ]
78use graphql_parser:: schema:: Document ;
89
5455 SubscriptionT : GraphQLType < DefaultScalarValue , TypeInfo = ( ) > ,
5556{
5657 /// Constructs a new [`RootNode`] from `query`, `mutation` and `subscription` nodes,
57- /// parametrizing it with a [`DefaultScalarValue`].
58+ /// parametrizing it with a [`DefaultScalarValue`] .
5859 pub fn new ( query : QueryT , mutation : MutationT , subscription : SubscriptionT ) -> Self {
5960 Self :: new_with_info ( query, mutation, subscription, ( ) , ( ) , ( ) )
6061 }
@@ -68,14 +69,67 @@ where
6869 SubscriptionT : GraphQLType < S , TypeInfo = ( ) > ,
6970{
7071 /// Constructs a new [`RootNode`] from `query`, `mutation` and `subscription` nodes,
71- /// parametrizing it with the provided [`ScalarValue`].
72+ /// parametrized it with the provided [`ScalarValue`].
7273 pub fn new_with_scalar_value (
7374 query : QueryT ,
7475 mutation : MutationT ,
7576 subscription : SubscriptionT ,
7677 ) -> Self {
7778 RootNode :: new_with_info ( query, mutation, subscription, ( ) , ( ) , ( ) )
7879 }
80+
81+ /// Constructs a new [`RootNode`] from `query`, `mutation` and `subscription` nodes,
82+ /// parametrized it with a [`ScalarValue`] and directives
83+ /// ```rust
84+ /// use juniper::{
85+ /// graphql_object, graphql_vars, EmptyMutation, EmptySubscription, GraphQLError,
86+ /// RootNode, DirectiveLocation , DirectiveType
87+ /// };
88+ ///
89+ /// struct Query{}
90+ ///
91+ /// #[graphql_object]
92+ /// impl Query {
93+ /// pub fn hello() -> String {
94+ /// "Hello".to_string()
95+ /// }
96+ /// }
97+ ///
98+ /// type Schema = RootNode<'static, Query, EmptyMutation, EmptySubscription>;
99+ ///
100+ /// let schema = Schema::new_with_directives(Query {}, EmptyMutation::new(), EmptySubscription::new()
101+ /// ,vec![ DirectiveType::new("my_directive", &[DirectiveLocation::Query] , &[] , false )]);
102+ ///
103+ /// let query = "query @my_directive { hello }";
104+ ///
105+ /// match juniper::execute_sync(query, None, &schema, &graphql_vars! {}, &()) {
106+ /// Err(GraphQLError::ValidationError(errs)) => { panic!("should not give an error"); }
107+ /// res => {}
108+ /// }
109+ ///
110+ /// let query = "query @non_existing_directive { hello }";
111+ ///
112+ /// match juniper::execute_sync(query, None, &schema, &graphql_vars! {}, &()) {
113+ /// Err(GraphQLError::ValidationError(errs)) => { }
114+ /// res => { panic!("should give an error"); }
115+ /// }
116+ /// ```
117+ pub fn new_with_directives (
118+ query : QueryT ,
119+ mutation : MutationT ,
120+ subscription : SubscriptionT ,
121+ custom_directives : Vec < DirectiveType < S > > ,
122+ ) -> Self {
123+ Self :: new_with_directives_and_info (
124+ query,
125+ mutation,
126+ subscription,
127+ custom_directives,
128+ ( ) ,
129+ ( ) ,
130+ ( ) ,
131+ )
132+ }
79133}
80134
81135impl < S , QueryT , MutationT , SubscriptionT > RootNode < QueryT , MutationT , SubscriptionT , S >
@@ -112,6 +166,34 @@ where
112166 }
113167 }
114168
169+ /// Construct a new root node with default meta types
170+ /// and with custom directives
171+ pub fn new_with_directives_and_info (
172+ query_obj : QueryT ,
173+ mutation_obj : MutationT ,
174+ subscription_obj : SubscriptionT ,
175+ custom_directives : Vec < DirectiveType < S > > ,
176+ query_info : QueryT :: TypeInfo ,
177+ mutation_info : MutationT :: TypeInfo ,
178+ subscription_info : SubscriptionT :: TypeInfo ,
179+ ) -> Self {
180+ Self {
181+ query_type : query_obj,
182+ mutation_type : mutation_obj,
183+ subscription_type : subscription_obj,
184+ schema : SchemaType :: new_with_directives :: < QueryT , MutationT , SubscriptionT > (
185+ & query_info,
186+ & mutation_info,
187+ & subscription_info,
188+ custom_directives. into ( ) ,
189+ ) ,
190+ query_info,
191+ mutation_info,
192+ subscription_info,
193+ introspection_disabled : false ,
194+ }
195+ }
196+
115197 /// Disables introspection for this [`RootNode`], making it to return a [`FieldError`] whenever
116198 /// its `__schema` or `__type` field is resolved.
117199 ///
@@ -214,7 +296,7 @@ pub struct SchemaType<S> {
214296 pub ( crate ) query_type_name : String ,
215297 pub ( crate ) mutation_type_name : Option < String > ,
216298 pub ( crate ) subscription_type_name : Option < String > ,
217- directives : FnvHashMap < ArcStr , DirectiveType < S > > ,
299+ pub ( crate ) directives : FnvHashMap < ArcStr , DirectiveType < S > > ,
218300}
219301
220302impl < S > Context for SchemaType < S > { }
@@ -226,6 +308,22 @@ impl<S> SchemaType<S> {
226308 mutation_info : & MutationT :: TypeInfo ,
227309 subscription_info : & SubscriptionT :: TypeInfo ,
228310 ) -> Self
311+ where
312+ S : ScalarValue ,
313+ QueryT : GraphQLType < S > ,
314+ MutationT : GraphQLType < S > ,
315+ SubscriptionT : GraphQLType < S > ,
316+ {
317+ Self :: new_with_directives :: < QueryT , MutationT , SubscriptionT > ( query_info, mutation_info, subscription_info, None )
318+ }
319+
320+ /// Create a new schema with custom directives
321+ pub fn new_with_directives < QueryT , MutationT , SubscriptionT > (
322+ query_info : & QueryT :: TypeInfo ,
323+ mutation_info : & MutationT :: TypeInfo ,
324+ subscription_info : & SubscriptionT :: TypeInfo ,
325+ custom_directives : Option < Vec < DirectiveType < S > > > ,
326+ ) -> Self
229327 where
230328 S : ScalarValue ,
231329 QueryT : GraphQLType < S > ,
@@ -259,6 +357,12 @@ impl<S> SchemaType<S> {
259357 directives. insert ( deprecated_directive. name . clone ( ) , deprecated_directive) ;
260358 directives. insert ( specified_by_directive. name . clone ( ) , specified_by_directive) ;
261359
360+ if let Some ( custom_directives) = custom_directives {
361+ for custom_directive in custom_directives. into_iter ( ) {
362+ directives. insert ( custom_directive. name . clone ( ) , custom_directive) ;
363+ }
364+ }
365+
262366 let mut meta_fields = vec ! [
263367 registry. field:: <SchemaType <S >>( arcstr:: literal!( "__schema" ) , & ( ) ) ,
264368 registry
@@ -601,6 +705,15 @@ impl<S> DirectiveType<S> {
601705 )
602706 }
603707
708+ /// skip,include,deprecated,specifiedBy are standard graphQL directive
709+ /// wiil not show up in generated scheme
710+ pub fn is_builtin ( & self ) -> bool {
711+ match self . name . as_str ( ) {
712+ "skip" | "include" | "deprecated" | "specifiedBy" => true ,
713+ _ => false ,
714+ }
715+ }
716+
604717 fn new_skip ( registry : & mut Registry < S > ) -> Self
605718 where
606719 S : ScalarValue ,
0 commit comments