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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Merge multiple [Juniper](https://docs.rs/juniper) object definitions into a single object type.
//!
//! [crates.io](https://crates.io/crates/juniper-compose) | [docs](https://docs.rs/juniper-compose) | [github](https://github.com/nikis05/juniper-compose)
//!
//! ## Motivation
//!
//! You are building a GraphQL server using Juniper. At some point you realize that you have gigantic
//! Query and Mutation types:
//!
//! ```
//! #[derive(Default)]
//! struct Query;
//!
//! #[juniper::graphql_object]
//! impl Query {
//! async fn user(ctx: &Context, id: Uuid) -> User {
//! // ...
//! }
//!
//! async fn users(ctx: &Context) -> Vec<User> {
//! // ...
//! }
//!
//! async fn task(ctx: &Context, id: Uuid) -> Task {
//! // ...
//! }
//!
//! async fn tasks(ctx: &Context) -> Vec<Task> {
//! // ...
//! }
//!
//! // ...many more
//! }
//! ```
//!
//! You would like to split it up into multiple domain-specific files, and have e.g. all User
//! queries in one file and all Task queries in the other. With current Juniper API, it is very
//! hard to do, but this crate can help you.
//!
//! ## Usage
//!
//! ```
//! #[derive(Default)]
//! struct UserQueries;
//!
//! #[composable_object]
//! #[juniper::graphql_object]
//! impl UserQueries {
//! async fn user(ctx: &Context, id: Uuid) -> User {
//! // ...
//! }
//!
//! async fn users(ctx: &Context) -> Vec<User> {
//! // ...
//! }
//! }
//!
//! #[derive(Default)]
//! struct TaskQueries;
//!
//! #[composable_object]
//! #[juniper::graphql_object]
//! impl TaskQueries {
//! async fn task(ctx: &Context, id: Uuid) -> Task {
//! // ...
//! }
//!
//! async fn tasks(ctx: &Context) -> Vec<Task> {
//! // ...
//! }
//! }
//!
//! composite_object!(Query(UserQueries, TaskQueries));
//! ```
//!
//! Custom contexts are supported:
//!
//! ```
//! composite_object!(Query<Context = MyCustomContext>(UserQueries, TaskQueries));
//! ```
//!
//! Visibility specifier for generated type is supported:
//!
//! ```
//! composite_object!(pub(crate) Query<Context = MyCustomContext>(UserQueries, TaskQueries));
//! ```
//!
//! Custom scalars are currently not supported, but will be added if requested.
use ;
use Cow;
/// Implements [ComposableObject](ComposableObject) for a GraphQL object type.
/// **Important**: must be applied before the `juniper::graphql_object` macro.
///
/// ## Example
///
/// ```
/// #[composable_object]
/// #[graphql_object]
/// impl UserQueries {
/// // ...
/// }
/// ```
pub use composable_object;
/// Composes an object type from multiple [ComposableObject](ComposableObject)s.
/// Custom context type may be specified, otherwise defaults to `()`.
/// Custom visibility fro generated type may be specified.
///
/// ## Examples
///
/// ```
/// composite_object!(Query(UserQueries, TaskQueries));
/// composite_object!(Mutation<Context = MyContextType>(UserMutations, TaskMutations));
/// composite_object!(pub Query(UserQueries, TaskQueries));
/// ```
pub use composite_object;
/// Object types that you want to compose into one must implement this trait.
/// Use [composable_object](composable_object) to implement it.