Skip to content

Commit 23a9e83

Browse files
committed
Fix #225 for schemagen
1 parent 0d42efd commit 23a9e83

File tree

12 files changed

+323
-29
lines changed

12 files changed

+323
-29
lines changed

include/SchemaLoader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ struct InputType
106106
InputFieldList fields;
107107
std::string_view description;
108108
std::unordered_set<std::string_view> dependencies {};
109-
std::vector<std::string_view> forwardDeclarations {};
109+
std::vector<std::string_view> declarations {};
110110
};
111111

112112
using InputTypeList = std::vector<InputType>;

include/graphqlservice/GraphQLService.h

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,15 @@ enum class TypeModifier
591591
List,
592592
};
593593

594+
template <typename Type>
595+
constexpr bool isInputType = false;
596+
597+
template <TypeModifier Modifier>
598+
constexpr bool isNoneModifier = (Modifier == TypeModifier::None);
599+
600+
template <TypeModifier... Other>
601+
constexpr bool trailingNoneModifiers = (... && isNoneModifer<Other>);
602+
594603
// Extract individual arguments with chained type modifiers which add nullable or list wrappers.
595604
// If the argument is not optional, use require and let it throw a schema_exception when the
596605
// argument is missing or not the correct type. If it's optional, use find and check the second
@@ -604,7 +613,8 @@ struct ModifiedArgument
604613
{
605614
// Peel off modifiers until we get to the underlying type.
606615
using type = typename std::conditional_t<TypeModifier::Nullable == Modifier,
607-
std::optional<typename ArgumentTraits<U, Other...>::type>,
616+
typename std::conditional_t<isInputType<U> && trailingNoneModifiers<Other...>,
617+
std::unique_ptr<U>, std::optional<typename ArgumentTraits<U, Other...>::type>>,
608618
typename std::conditional_t<TypeModifier::List == Modifier,
609619
std::vector<typename ArgumentTraits<U, Other...>::type>, U>>;
610620
};
@@ -678,12 +688,19 @@ struct ModifiedArgument
678688
if (valueItr == arguments.get<response::MapType>().cend()
679689
|| valueItr->second.type() == response::Type::Null)
680690
{
681-
return std::nullopt;
691+
return {};
682692
}
683693

684694
auto result = require<Other...>(name, arguments);
685695

686-
return std::make_optional<decltype(result)>(std::move(result));
696+
if constexpr (isInputType<Type> && trailingNoneModifiers<Other...>)
697+
{
698+
return std::make_unique<decltype(result)>(std::move(result));
699+
}
700+
else
701+
{
702+
return std::make_optional<decltype(result)>(std::move(result));
703+
}
687704
}
688705

689706
// Peel off list modifiers.

samples/learn/schema/StarWarsSchema.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ void AddMutationDetails(const std::shared_ptr<schema::ObjectType>& typeMutation,
8686
std::shared_ptr<schema::Schema> GetSchema();
8787

8888
} // namespace learn
89+
90+
namespace service {
91+
92+
template <>
93+
constexpr bool isInputType<learn::ReviewInput> = true;
94+
95+
} // namespace service
8996
} // namespace graphql
9097

9198
#endif // STARWARSSCHEMA_H

samples/today/nointrospection/TodaySchema.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ today::FourthNestedInput ModifiedArgument<today::FourthNestedInput>::convert(con
125125
};
126126
}
127127

128+
template <>
129+
today::IncludeNullableSelfInput ModifiedArgument<today::IncludeNullableSelfInput>::convert(const response::Value& value)
130+
{
131+
auto valueSelf = service::ModifiedArgument<today::IncludeNullableSelfInput>::require<service::TypeModifier::Nullable>("self", value);
132+
133+
return {
134+
std::move(valueSelf)
135+
};
136+
}
137+
138+
template <>
139+
today::IncludeNonNullableListSelfInput ModifiedArgument<today::IncludeNonNullableListSelfInput>::convert(const response::Value& value)
140+
{
141+
auto valueSelves = service::ModifiedArgument<today::IncludeNonNullableListSelfInput>::require<service::TypeModifier::List>("selves", value);
142+
143+
return {
144+
std::move(valueSelves)
145+
};
146+
}
147+
128148
template <>
129149
today::SecondNestedInput ModifiedArgument<today::SecondNestedInput>::convert(const response::Value& value)
130150
{
@@ -137,6 +157,18 @@ today::SecondNestedInput ModifiedArgument<today::SecondNestedInput>::convert(con
137157
};
138158
}
139159

160+
template <>
161+
today::ForwardDeclaredInput ModifiedArgument<today::ForwardDeclaredInput>::convert(const response::Value& value)
162+
{
163+
auto valueNullableSelf = service::ModifiedArgument<today::IncludeNullableSelfInput>::require<service::TypeModifier::Nullable>("nullableSelf", value);
164+
auto valueListSelves = service::ModifiedArgument<today::IncludeNonNullableListSelfInput>::require("listSelves", value);
165+
166+
return {
167+
std::move(valueNullableSelf),
168+
std::move(valueListSelves)
169+
};
170+
}
171+
140172
template <>
141173
today::FirstNestedInput ModifiedArgument<today::FirstNestedInput>::convert(const response::Value& value)
142174
{
@@ -179,8 +211,14 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
179211
schema->AddType(R"gql(ThirdNestedInput)gql"sv, typeThirdNestedInput);
180212
auto typeFourthNestedInput = schema::InputObjectType::Make(R"gql(FourthNestedInput)gql"sv, R"md()md"sv);
181213
schema->AddType(R"gql(FourthNestedInput)gql"sv, typeFourthNestedInput);
214+
auto typeIncludeNullableSelfInput = schema::InputObjectType::Make(R"gql(IncludeNullableSelfInput)gql"sv, R"md()md"sv);
215+
schema->AddType(R"gql(IncludeNullableSelfInput)gql"sv, typeIncludeNullableSelfInput);
216+
auto typeIncludeNonNullableListSelfInput = schema::InputObjectType::Make(R"gql(IncludeNonNullableListSelfInput)gql"sv, R"md()md"sv);
217+
schema->AddType(R"gql(IncludeNonNullableListSelfInput)gql"sv, typeIncludeNonNullableListSelfInput);
182218
auto typeSecondNestedInput = schema::InputObjectType::Make(R"gql(SecondNestedInput)gql"sv, R"md()md"sv);
183219
schema->AddType(R"gql(SecondNestedInput)gql"sv, typeSecondNestedInput);
220+
auto typeForwardDeclaredInput = schema::InputObjectType::Make(R"gql(ForwardDeclaredInput)gql"sv, R"md()md"sv);
221+
schema->AddType(R"gql(ForwardDeclaredInput)gql"sv, typeForwardDeclaredInput);
184222
auto typeFirstNestedInput = schema::InputObjectType::Make(R"gql(FirstNestedInput)gql"sv, R"md()md"sv);
185223
schema->AddType(R"gql(FirstNestedInput)gql"sv, typeFirstNestedInput);
186224
auto typeNode = schema::InterfaceType::Make(R"gql(Node)gql"sv, R"md()md"sv);
@@ -239,10 +277,20 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
239277
typeFourthNestedInput->AddInputValues({
240278
schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv)
241279
});
280+
typeIncludeNullableSelfInput->AddInputValues({
281+
schema::InputValue::Make(R"gql(self)gql"sv, R"md()md"sv, schema->LookupType(R"gql(IncludeNullableSelfInput)gql"sv), R"gql()gql"sv)
282+
});
283+
typeIncludeNonNullableListSelfInput->AddInputValues({
284+
schema::InputValue::Make(R"gql(selves)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(IncludeNonNullableListSelfInput)gql"sv)))), R"gql()gql"sv)
285+
});
242286
typeSecondNestedInput->AddInputValues({
243287
schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv),
244288
schema::InputValue::Make(R"gql(third)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ThirdNestedInput)gql"sv)), R"gql()gql"sv)
245289
});
290+
typeForwardDeclaredInput->AddInputValues({
291+
schema::InputValue::Make(R"gql(nullableSelf)gql"sv, R"md()md"sv, schema->LookupType(R"gql(IncludeNullableSelfInput)gql"sv), R"gql()gql"sv),
292+
schema::InputValue::Make(R"gql(listSelves)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(IncludeNonNullableListSelfInput)gql"sv)), R"gql()gql"sv)
293+
});
246294
typeFirstNestedInput->AddInputValues({
247295
schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv),
248296
schema::InputValue::Make(R"gql(second)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(SecondNestedInput)gql"sv)), R"gql()gql"sv),

samples/today/nointrospection/TodaySchema.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,28 @@ struct FourthNestedInput
6060
response::IdType id {};
6161
};
6262

63+
struct IncludeNullableSelfInput
64+
{
65+
std::unique_ptr<IncludeNullableSelfInput> self {};
66+
};
67+
68+
struct IncludeNonNullableListSelfInput
69+
{
70+
std::vector<IncludeNonNullableListSelfInput> selves {};
71+
};
72+
6373
struct SecondNestedInput
6474
{
6575
response::IdType id {};
6676
ThirdNestedInput third {};
6777
};
6878

79+
struct ForwardDeclaredInput
80+
{
81+
std::unique_ptr<IncludeNullableSelfInput> nullableSelf {};
82+
IncludeNonNullableListSelfInput listSelves {};
83+
};
84+
6985
struct FirstNestedInput
7086
{
7187
response::IdType id {};
@@ -140,6 +156,27 @@ void AddExpensiveDetails(const std::shared_ptr<schema::ObjectType>& typeExpensiv
140156
std::shared_ptr<schema::Schema> GetSchema();
141157

142158
} // namespace today
159+
160+
namespace service {
161+
162+
template <>
163+
constexpr bool isInputType<today::CompleteTaskInput> = true;
164+
template <>
165+
constexpr bool isInputType<today::ThirdNestedInput> = true;
166+
template <>
167+
constexpr bool isInputType<today::FourthNestedInput> = true;
168+
template <>
169+
constexpr bool isInputType<today::IncludeNullableSelfInput> = true;
170+
template <>
171+
constexpr bool isInputType<today::IncludeNonNullableListSelfInput> = true;
172+
template <>
173+
constexpr bool isInputType<today::SecondNestedInput> = true;
174+
template <>
175+
constexpr bool isInputType<today::ForwardDeclaredInput> = true;
176+
template <>
177+
constexpr bool isInputType<today::FirstNestedInput> = true;
178+
179+
} // namespace service
143180
} // namespace graphql
144181

145182
#endif // TODAYSCHEMA_H

samples/today/schema.today.graphql

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,15 @@ input FourthNestedInput {
185185
id: ID!
186186
}
187187

188-
#input IncludeNullableSelfInput {
189-
# self: IncludeNullableSelfInput
190-
#}
191-
#
192-
#input IncludeNonNullableListSelfInput {
193-
# selves: [IncludeNonNullableListSelfInput!]!
194-
#}
188+
input ForwardDeclaredInput {
189+
nullableSelf: IncludeNullableSelfInput
190+
listSelves: IncludeNonNullableListSelfInput!
191+
}
192+
193+
input IncludeNullableSelfInput {
194+
self: IncludeNullableSelfInput
195+
}
196+
197+
input IncludeNonNullableListSelfInput {
198+
selves: [IncludeNonNullableListSelfInput!]!
199+
}

samples/today/schema/TodaySchema.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ today::FourthNestedInput ModifiedArgument<today::FourthNestedInput>::convert(con
125125
};
126126
}
127127

128+
template <>
129+
today::IncludeNullableSelfInput ModifiedArgument<today::IncludeNullableSelfInput>::convert(const response::Value& value)
130+
{
131+
auto valueSelf = service::ModifiedArgument<today::IncludeNullableSelfInput>::require<service::TypeModifier::Nullable>("self", value);
132+
133+
return {
134+
std::move(valueSelf)
135+
};
136+
}
137+
138+
template <>
139+
today::IncludeNonNullableListSelfInput ModifiedArgument<today::IncludeNonNullableListSelfInput>::convert(const response::Value& value)
140+
{
141+
auto valueSelves = service::ModifiedArgument<today::IncludeNonNullableListSelfInput>::require<service::TypeModifier::List>("selves", value);
142+
143+
return {
144+
std::move(valueSelves)
145+
};
146+
}
147+
128148
template <>
129149
today::SecondNestedInput ModifiedArgument<today::SecondNestedInput>::convert(const response::Value& value)
130150
{
@@ -137,6 +157,18 @@ today::SecondNestedInput ModifiedArgument<today::SecondNestedInput>::convert(con
137157
};
138158
}
139159

160+
template <>
161+
today::ForwardDeclaredInput ModifiedArgument<today::ForwardDeclaredInput>::convert(const response::Value& value)
162+
{
163+
auto valueNullableSelf = service::ModifiedArgument<today::IncludeNullableSelfInput>::require<service::TypeModifier::Nullable>("nullableSelf", value);
164+
auto valueListSelves = service::ModifiedArgument<today::IncludeNonNullableListSelfInput>::require("listSelves", value);
165+
166+
return {
167+
std::move(valueNullableSelf),
168+
std::move(valueListSelves)
169+
};
170+
}
171+
140172
template <>
141173
today::FirstNestedInput ModifiedArgument<today::FirstNestedInput>::convert(const response::Value& value)
142174
{
@@ -179,8 +211,14 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
179211
schema->AddType(R"gql(ThirdNestedInput)gql"sv, typeThirdNestedInput);
180212
auto typeFourthNestedInput = schema::InputObjectType::Make(R"gql(FourthNestedInput)gql"sv, R"md()md"sv);
181213
schema->AddType(R"gql(FourthNestedInput)gql"sv, typeFourthNestedInput);
214+
auto typeIncludeNullableSelfInput = schema::InputObjectType::Make(R"gql(IncludeNullableSelfInput)gql"sv, R"md()md"sv);
215+
schema->AddType(R"gql(IncludeNullableSelfInput)gql"sv, typeIncludeNullableSelfInput);
216+
auto typeIncludeNonNullableListSelfInput = schema::InputObjectType::Make(R"gql(IncludeNonNullableListSelfInput)gql"sv, R"md()md"sv);
217+
schema->AddType(R"gql(IncludeNonNullableListSelfInput)gql"sv, typeIncludeNonNullableListSelfInput);
182218
auto typeSecondNestedInput = schema::InputObjectType::Make(R"gql(SecondNestedInput)gql"sv, R"md()md"sv);
183219
schema->AddType(R"gql(SecondNestedInput)gql"sv, typeSecondNestedInput);
220+
auto typeForwardDeclaredInput = schema::InputObjectType::Make(R"gql(ForwardDeclaredInput)gql"sv, R"md()md"sv);
221+
schema->AddType(R"gql(ForwardDeclaredInput)gql"sv, typeForwardDeclaredInput);
184222
auto typeFirstNestedInput = schema::InputObjectType::Make(R"gql(FirstNestedInput)gql"sv, R"md()md"sv);
185223
schema->AddType(R"gql(FirstNestedInput)gql"sv, typeFirstNestedInput);
186224
auto typeNode = schema::InterfaceType::Make(R"gql(Node)gql"sv, R"md(Node interface for Relay support)md"sv);
@@ -242,10 +280,20 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
242280
typeFourthNestedInput->AddInputValues({
243281
schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv)
244282
});
283+
typeIncludeNullableSelfInput->AddInputValues({
284+
schema::InputValue::Make(R"gql(self)gql"sv, R"md()md"sv, schema->LookupType(R"gql(IncludeNullableSelfInput)gql"sv), R"gql()gql"sv)
285+
});
286+
typeIncludeNonNullableListSelfInput->AddInputValues({
287+
schema::InputValue::Make(R"gql(selves)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->WrapType(introspection::TypeKind::LIST, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(IncludeNonNullableListSelfInput)gql"sv)))), R"gql()gql"sv)
288+
});
245289
typeSecondNestedInput->AddInputValues({
246290
schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv),
247291
schema::InputValue::Make(R"gql(third)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ThirdNestedInput)gql"sv)), R"gql()gql"sv)
248292
});
293+
typeForwardDeclaredInput->AddInputValues({
294+
schema::InputValue::Make(R"gql(nullableSelf)gql"sv, R"md()md"sv, schema->LookupType(R"gql(IncludeNullableSelfInput)gql"sv), R"gql()gql"sv),
295+
schema::InputValue::Make(R"gql(listSelves)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(IncludeNonNullableListSelfInput)gql"sv)), R"gql()gql"sv)
296+
});
249297
typeFirstNestedInput->AddInputValues({
250298
schema::InputValue::Make(R"gql(id)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(ID)gql"sv)), R"gql()gql"sv),
251299
schema::InputValue::Make(R"gql(second)gql"sv, R"md()md"sv, schema->WrapType(introspection::TypeKind::NON_NULL, schema->LookupType(R"gql(SecondNestedInput)gql"sv)), R"gql()gql"sv),

samples/today/schema/TodaySchema.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,28 @@ struct FourthNestedInput
6060
response::IdType id {};
6161
};
6262

63+
struct IncludeNullableSelfInput
64+
{
65+
std::unique_ptr<IncludeNullableSelfInput> self {};
66+
};
67+
68+
struct IncludeNonNullableListSelfInput
69+
{
70+
std::vector<IncludeNonNullableListSelfInput> selves {};
71+
};
72+
6373
struct SecondNestedInput
6474
{
6575
response::IdType id {};
6676
ThirdNestedInput third {};
6777
};
6878

79+
struct ForwardDeclaredInput
80+
{
81+
std::unique_ptr<IncludeNullableSelfInput> nullableSelf {};
82+
IncludeNonNullableListSelfInput listSelves {};
83+
};
84+
6985
struct FirstNestedInput
7086
{
7187
response::IdType id {};
@@ -140,6 +156,27 @@ void AddExpensiveDetails(const std::shared_ptr<schema::ObjectType>& typeExpensiv
140156
std::shared_ptr<schema::Schema> GetSchema();
141157

142158
} // namespace today
159+
160+
namespace service {
161+
162+
template <>
163+
constexpr bool isInputType<today::CompleteTaskInput> = true;
164+
template <>
165+
constexpr bool isInputType<today::ThirdNestedInput> = true;
166+
template <>
167+
constexpr bool isInputType<today::FourthNestedInput> = true;
168+
template <>
169+
constexpr bool isInputType<today::IncludeNullableSelfInput> = true;
170+
template <>
171+
constexpr bool isInputType<today::IncludeNonNullableListSelfInput> = true;
172+
template <>
173+
constexpr bool isInputType<today::SecondNestedInput> = true;
174+
template <>
175+
constexpr bool isInputType<today::ForwardDeclaredInput> = true;
176+
template <>
177+
constexpr bool isInputType<today::FirstNestedInput> = true;
178+
179+
} // namespace service
143180
} // namespace graphql
144181

145182
#endif // TODAYSCHEMA_H

0 commit comments

Comments
 (0)