1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Components for integrating GraphQL endpoints into Tsukuyomi.

#![doc(html_root_url = "https://docs.rs/tsukuyomi-juniper/0.4.0-dev")]
#![deny(
    missing_docs,
    missing_debug_implementations,
    nonstandard_style,
    rust_2018_idioms,
    rust_2018_compatibility,
    unused
)]
#![forbid(clippy::unimplemented)]

mod error;
mod graphiql;
mod request;

pub use crate::{
    error::{capture_errors, CaptureErrors},
    graphiql::graphiql_source,
    request::{request, GraphQLRequest, GraphQLResponse},
};

use {
    juniper::{DefaultScalarValue, GraphQLType, RootNode, ScalarRefValue, ScalarValue},
    std::sync::Arc,
};

/// A marker trait representing a root node of GraphQL schema.
#[allow(missing_docs)]
pub trait Schema<S = DefaultScalarValue>
where
    S: ScalarValue,
    for<'a> &'a S: ScalarRefValue<'a>,
{
    type Query: GraphQLType<S, Context = Self::Context, TypeInfo = Self::QueryInfo>;
    type QueryInfo;
    type Mutation: GraphQLType<S, Context = Self::Context, TypeInfo = Self::MutationInfo>;
    type MutationInfo;
    type Context;

    fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation, S>;
}

impl<QueryT, MutationT, CtxT, S> Schema<S> for RootNode<'static, QueryT, MutationT, S>
where
    QueryT: GraphQLType<S, Context = CtxT>,
    MutationT: GraphQLType<S, Context = CtxT>,
    S: ScalarValue,
    for<'a> &'a S: ScalarRefValue<'a>,
{
    type Query = QueryT;
    type QueryInfo = QueryT::TypeInfo;
    type Mutation = MutationT;
    type MutationInfo = MutationT::TypeInfo;
    type Context = CtxT;

    #[inline]
    fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation, S> {
        self
    }
}

impl<T, S> Schema<S> for Box<T>
where
    T: Schema<S>,
    S: ScalarValue,
    for<'a> &'a S: ScalarRefValue<'a>,
{
    type Query = T::Query;
    type QueryInfo = T::QueryInfo;
    type Mutation = T::Mutation;
    type MutationInfo = T::MutationInfo;
    type Context = T::Context;

    #[inline]
    fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation, S> {
        (**self).as_root_node()
    }
}

impl<T, S> Schema<S> for Arc<T>
where
    T: Schema<S>,
    S: ScalarValue,
    for<'a> &'a S: ScalarRefValue<'a>,
{
    type Query = T::Query;
    type QueryInfo = T::QueryInfo;
    type Mutation = T::Mutation;
    type MutationInfo = T::MutationInfo;
    type Context = T::Context;

    #[inline]
    fn as_root_node(&self) -> &RootNode<'static, Self::Query, Self::Mutation, S> {
        (**self).as_root_node()
    }
}