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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! 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:
//!
//! ```ignore
//! #[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
//!
//! ```ignore
//! use juniper_compose_ng::{composable_object, composite_object};
//! use juniper::graphql_object;
//!
//! // Define your types and context
//! struct Context;
//! #[derive(juniper::GraphQLObject)] struct User { id: String }
//! #[derive(juniper::GraphQLObject)] struct Task { id: String }
//!
//! // Define composable query objects
//! #[derive(Default)]
//! struct UserQueries;
//!
//! #[composable_object]
//! #[graphql_object]
//! impl UserQueries {
//! async fn user(&self, ctx: &Context, id: String) -> User {
//! User { id }
//! }
//! }
//!
//! #[derive(Default)]
//! struct TaskQueries;
//!
//! #[composable_object]
//! #[graphql_object]
//! impl TaskQueries {
//! async fn task(&self, ctx: &Context, id: String) -> Task {
//! Task { id }
//! }
//! }
//!
//! // Compose them into a single Query type
//! composite_object!(Query(UserQueries, TaskQueries));
//! ```
//!
//! Custom contexts are supported:
//!
//! ```ignore
//! use juniper_compose_ng::composite_object;
//!
//! struct MyCustomContext;
//! #[derive(Default)] struct UserQueries;
//! #[derive(Default)] struct TaskQueries;
//!
//! composite_object!(Query<Context = MyCustomContext>(UserQueries, TaskQueries));
//! ```
//!
//! Visibility specifier for generated type is supported:
//!
//! ```ignore
//! use juniper_compose_ng::composite_object;
//!
//! struct MyCustomContext;
//! #[derive(Default)] struct UserQueries;
//! #[derive(Default)] struct TaskQueries;
//!
//! 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
///
/// ```ignore
/// use juniper_compose_ng::composable_object;
/// use juniper::graphql_object;
///
/// #[derive(Default)] struct UserQueries;
///
/// #[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
///
/// ```ignore
/// use juniper_compose_ng::composite_object;
///
/// #[derive(Default)] struct UserQueries;
/// #[derive(Default)] struct TaskQueries;
/// #[derive(Default)] struct UserMutations;
/// #[derive(Default)] struct TaskMutations;
/// struct MyContextType;
///
/// composite_object!(Query(UserQueries, TaskQueries));
/// composite_object!(Mutation<Context = MyContextType>(UserMutations, TaskMutations));
/// composite_object!(pub QueryPublic(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.