Skip to content

Commit 3fb36ba

Browse files
committed
Merge branch 'main' into more-constexpr-schema
2 parents bf087e1 + 9afda58 commit 3fb36ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1455
-423
lines changed

.github/workflows/windows.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Windows
33
on: [push, pull_request]
44

55
jobs:
6-
vs2019:
6+
vs2022:
77
strategy:
88
fail-fast: false
99
matrix:
@@ -52,7 +52,7 @@ jobs:
5252
$cmakeSharedLibs = $(if ('${{ matrix.libs }}' -eq 'shared') { 'ON' } else { 'OFF' })
5353
$msbuildArch = $(if ('${{ matrix.arch }}' -eq 'x64') { 'X64' } else { 'Win32' })
5454
55-
cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DVCPKG_TARGET_TRIPLET=$vcpkgTriplet" "-DBUILD_SHARED_LIBS=$cmakeSharedLibs" -G "Visual Studio 16 2019" -A "$msbuildArch" ${{ github.workspace }}
55+
cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DVCPKG_TARGET_TRIPLET=$vcpkgTriplet" "-DBUILD_SHARED_LIBS=$cmakeSharedLibs" -G "Visual Studio 17 2022" -A "$msbuildArch" ${{ github.workspace }}
5656
5757
- name: Build
5858
working-directory: build/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ the license text. Please see the license or copyright notice which comes with ea
109109

110110
### graphqlpeg
111111

112-
- GraphQL parsing: [Parsing Expression Grammar Template Library (PEGTL)](https://github.com/taocpp/PEGTL) release 3.2.2,
112+
- GraphQL parsing: [Parsing Expression Grammar Template Library (PEGTL)](https://github.com/taocpp/PEGTL) release 3.2.5,
113113
which is part of [The Art of C++](https://taocpp.github.io/) library collection. I've added this as a sub-module, so you
114-
do not need to install this separately. If you already have 3.2.2 installed where CMake can find it, it will use that
114+
do not need to install this separately. If you already have 3.2.5 installed where CMake can find it, it will use that
115115
instead of the sub-module and avoid installing another copy of PEGTL.
116116

117117
### graphqlservice

cmake/cppgraphqlgen-update-client-files.cmake

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ endforeach()
3838

3939
# Don't update the files in the source directory if no files were generated in the binary directory.
4040
if(NOT FILE_NAMES)
41-
message(FATAL_ERROR "Schema generation failed!")
41+
message(FATAL_ERROR "Client generation failed!")
4242
endif()
4343

4444
# Support if() IN_LIST operator: https://cmake.org/cmake/help/latest/policy/CMP0057.html
@@ -48,8 +48,10 @@ cmake_policy(SET CMP0057 NEW)
4848
file(GLOB OLD_FILES ${CLIENT_SOURCE_DIR}/*.h ${CLIENT_SOURCE_DIR}/*.cpp)
4949
foreach(OLD_FILE ${OLD_FILES})
5050
get_filename_component(OLD_FILE ${OLD_FILE} NAME)
51-
if(NOT OLD_FILE IN_LIST FILE_NAMES)
52-
file(REMOVE "${CLIENT_SOURCE_DIR}/${OLD_FILE}")
51+
if(NOT OLD_FILE IN_LIST FILE_NAMES AND
52+
NOT OLD_FILE STREQUAL "${CLIENT_PREFIX}Client.h" AND
53+
NOT OLD_FILE STREQUAL "${CLIENT_PREFIX}Client.cpp")
54+
message(WARNING "Unexpected file in ${CLIENT_TARGET} client sources: ${OLD_FILE}")
5355
endif()
5456
endforeach()
5557

cmake/cppgraphqlgen-update-schema-files.cmake

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ file(GLOB OLD_FILES ${SCHEMA_SOURCE_DIR}/*.h ${SCHEMA_SOURCE_DIR}/*.cpp)
4848
foreach(OLD_FILE ${OLD_FILES})
4949
get_filename_component(OLD_FILE ${OLD_FILE} NAME)
5050
if(NOT OLD_FILE IN_LIST FILE_NAMES)
51-
file(REMOVE "${SCHEMA_SOURCE_DIR}/${OLD_FILE}")
51+
if(OLD_FILE MATCHES "Object\\.h$" OR OLD_FILE MATCHES "Object\\.cpp$")
52+
file(REMOVE "${SCHEMA_SOURCE_DIR}/${OLD_FILE}")
53+
elseif(NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.h" AND
54+
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp")
55+
message(WARNING "Unexpected file in ${SCHEMA_TARGET} GraphQL schema sources: ${OLD_FILE}")
56+
endif()
5257
endif()
5358
endforeach()
5459

cmake/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.1.1
1+
4.2.0

include/SchemaLoader.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ struct OutputField
154154
{
155155
std::string_view type;
156156
std::string_view name;
157-
std::string_view cppName;
158157
InputFieldList arguments;
159158
OutputFieldType fieldType = OutputFieldType::Builtin;
160159
TypeModifierStack modifiers;
@@ -263,6 +262,9 @@ class SchemaLoader
263262
std::string getInputCppType(const InputField& field) const noexcept;
264263
std::string getOutputCppType(const OutputField& field) const noexcept;
265264

265+
static std::string getOutputCppAccessor(const OutputField& field) noexcept;
266+
static std::string getOutputCppResolver(const OutputField& field) noexcept;
267+
266268
private:
267269
static bool isExtension(const peg::ast_node& definition) noexcept;
268270

@@ -303,6 +305,8 @@ class SchemaLoader
303305
void validateTransitiveInterfaces(
304306
std::string_view typeName, const std::vector<std::string_view>& interfaces) const;
305307

308+
static std::string getJoinedCppName(std::string_view prefix, std::string_view fieldName) noexcept;
309+
306310
static const std::string_view s_introspectionNamespace;
307311
static const BuiltinTypeMap s_builtinTypes;
308312
static const CppTypeMap s_builtinCppTypes;

include/graphqlservice/GraphQLClient.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,12 @@ struct ModifiedResponse
188188
};
189189

190190
// Parse a single value of the response document.
191-
static Type parse(response::Value response);
191+
static Type parse(response::Value&& response);
192192

193193
// Peel off the none modifier. If it's included, it should always be last in the list.
194194
template <TypeModifier Modifier = TypeModifier::None, TypeModifier... Other>
195195
static typename std::enable_if_t<TypeModifier::None == Modifier && sizeof...(Other) == 0, Type>
196-
parse(response::Value response)
196+
parse(response::Value&& response)
197197
{
198198
return parse(std::move(response));
199199
}
@@ -202,7 +202,7 @@ struct ModifiedResponse
202202
template <TypeModifier Modifier, TypeModifier... Other>
203203
static typename std::enable_if_t<TypeModifier::Nullable == Modifier,
204204
std::optional<typename ResponseTraits<Type, Other...>::type>>
205-
parse(response::Value response)
205+
parse(response::Value&& response)
206206
{
207207
if (response.type() == response::Type::Null)
208208
{
@@ -217,7 +217,7 @@ struct ModifiedResponse
217217
template <TypeModifier Modifier, TypeModifier... Other>
218218
static typename std::enable_if_t<TypeModifier::List == Modifier,
219219
std::vector<typename ResponseTraits<Type, Other...>::type>>
220-
parse(response::Value response)
220+
parse(response::Value&& response)
221221
{
222222
std::vector<typename ResponseTraits<Type, Other...>::type> result;
223223

@@ -251,19 +251,19 @@ using ScalarResponse = ModifiedResponse<response::Value>;
251251
#ifdef GRAPHQL_DLLEXPORTS
252252
// Export all of the built-in converters
253253
template <>
254-
GRAPHQLCLIENT_EXPORT int ModifiedResponse<int>::parse(response::Value response);
254+
GRAPHQLCLIENT_EXPORT int ModifiedResponse<int>::parse(response::Value&& response);
255255
template <>
256-
GRAPHQLCLIENT_EXPORT double ModifiedResponse<double>::parse(response::Value response);
256+
GRAPHQLCLIENT_EXPORT double ModifiedResponse<double>::parse(response::Value&& response);
257257
template <>
258-
GRAPHQLCLIENT_EXPORT std::string ModifiedResponse<std::string>::parse(response::Value response);
258+
GRAPHQLCLIENT_EXPORT std::string ModifiedResponse<std::string>::parse(response::Value&& response);
259259
template <>
260-
GRAPHQLCLIENT_EXPORT bool ModifiedResponse<bool>::parse(response::Value response);
260+
GRAPHQLCLIENT_EXPORT bool ModifiedResponse<bool>::parse(response::Value&& response);
261261
template <>
262262
GRAPHQLCLIENT_EXPORT response::IdType ModifiedResponse<response::IdType>::parse(
263-
response::Value response);
263+
response::Value&& response);
264264
template <>
265265
GRAPHQLCLIENT_EXPORT response::Value ModifiedResponse<response::Value>::parse(
266-
response::Value response);
266+
response::Value&& response);
267267
#endif // GRAPHQL_DLLEXPORTS
268268

269269
} // namespace graphql::client

include/graphqlservice/GraphQLParse.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,17 @@ struct ast
3434
bool validated = false;
3535
};
3636

37-
GRAPHQLPEG_EXPORT ast parseSchemaString(std::string_view input);
38-
GRAPHQLPEG_EXPORT ast parseSchemaFile(std::string_view filename);
37+
// By default, we want to limit the depth of nested nodes. You can override this with
38+
// another value for the depthLimit parameter in these parse functions.
39+
constexpr size_t c_defaultDepthLimit = 25;
3940

40-
GRAPHQLPEG_EXPORT ast parseString(std::string_view input);
41-
GRAPHQLPEG_EXPORT ast parseFile(std::string_view filename);
41+
GRAPHQLPEG_EXPORT ast parseSchemaString(
42+
std::string_view input, size_t depthLimit = c_defaultDepthLimit);
43+
GRAPHQLPEG_EXPORT ast parseSchemaFile(
44+
std::string_view filename, size_t depthLimit = c_defaultDepthLimit);
45+
46+
GRAPHQLPEG_EXPORT ast parseString(std::string_view input, size_t depthLimit = c_defaultDepthLimit);
47+
GRAPHQLPEG_EXPORT ast parseFile(std::string_view filename, size_t depthLimit = c_defaultDepthLimit);
4248

4349
} // namespace peg
4450

include/graphqlservice/GraphQLResponse.h

Lines changed: 80 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include "graphqlservice/internal/Awaitable.h"
2222

23+
#include <cstdint>
24+
#include <initializer_list>
2325
#include <memory>
2426
#include <string>
2527
#include <string_view>
@@ -31,7 +33,7 @@ namespace graphql::response {
3133
// GraphQL responses are not technically JSON-specific, although that is probably the most common
3234
// way of representing them. These are the primitive types that may be represented in GraphQL, as
3335
// of the [October 2021 spec](https://spec.graphql.org/October2021/#sec-Serialization-Format).
34-
enum class Type : uint8_t
36+
enum class Type : std::uint8_t
3537
{
3638
Map, // JSON Object
3739
List, // JSON Array
@@ -41,6 +43,7 @@ enum class Type : uint8_t
4143
Int, // JSON Number
4244
Float, // JSON Number
4345
EnumValue, // JSON String
46+
ID, // JSON String
4447
Scalar, // JSON any type
4548
};
4649

@@ -53,13 +56,70 @@ using BooleanType = bool;
5356
using IntType = int;
5457
using FloatType = double;
5558
using ScalarType = Value;
56-
using IdType = std::vector<uint8_t>;
59+
60+
struct IdType
61+
{
62+
using ByteData = std::vector<std::uint8_t>;
63+
using OpaqueString = std::string;
64+
65+
GRAPHQLRESPONSE_EXPORT IdType(IdType&& other = IdType { ByteData {} }) noexcept;
66+
GRAPHQLRESPONSE_EXPORT IdType(const IdType& other);
67+
GRAPHQLRESPONSE_EXPORT ~IdType();
68+
69+
// Implicit ByteData constructors
70+
GRAPHQLRESPONSE_EXPORT IdType(size_t count, typename ByteData::value_type value = 0);
71+
GRAPHQLRESPONSE_EXPORT IdType(std::initializer_list<typename ByteData::value_type> values);
72+
GRAPHQLRESPONSE_EXPORT IdType(
73+
typename ByteData::const_iterator begin, typename ByteData::const_iterator end);
74+
75+
// Assignment
76+
GRAPHQLRESPONSE_EXPORT IdType& operator=(IdType&& rhs) noexcept;
77+
IdType& operator=(const IdType& rhs) = delete;
78+
79+
// Conversion
80+
GRAPHQLRESPONSE_EXPORT IdType(ByteData&& data) noexcept;
81+
GRAPHQLRESPONSE_EXPORT IdType& operator=(ByteData&& data) noexcept;
82+
83+
GRAPHQLRESPONSE_EXPORT IdType(OpaqueString&& opaque) noexcept;
84+
GRAPHQLRESPONSE_EXPORT IdType& operator=(OpaqueString&& opaque) noexcept;
85+
86+
template <typename ValueType>
87+
const ValueType& get() const;
88+
89+
template <typename ValueType>
90+
ValueType release();
91+
92+
// Comparison
93+
GRAPHQLRESPONSE_EXPORT bool operator==(const IdType& rhs) const noexcept;
94+
GRAPHQLRESPONSE_EXPORT bool operator==(const ByteData& rhs) const noexcept;
95+
GRAPHQLRESPONSE_EXPORT bool operator==(const OpaqueString& rhs) const noexcept;
96+
97+
GRAPHQLRESPONSE_EXPORT bool operator<(const IdType& rhs) const noexcept;
98+
99+
// Check the Type
100+
GRAPHQLRESPONSE_EXPORT bool isBase64() const noexcept;
101+
102+
private:
103+
std::variant<ByteData, OpaqueString> _data;
104+
};
105+
106+
#ifdef GRAPHQL_DLLEXPORTS
107+
// Export all of the specialized template methods
108+
template <>
109+
GRAPHQLRESPONSE_EXPORT const IdType::ByteData& IdType::get<IdType::ByteData>() const;
110+
template <>
111+
GRAPHQLRESPONSE_EXPORT const IdType::OpaqueString& IdType::get<IdType::OpaqueString>() const;
112+
template <>
113+
GRAPHQLRESPONSE_EXPORT IdType::ByteData IdType::release<IdType::ByteData>();
114+
template <>
115+
GRAPHQLRESPONSE_EXPORT IdType::OpaqueString IdType::release<IdType::OpaqueString>();
116+
#endif // GRAPHQL_DLLEXPORTS
57117

58118
template <typename ValueType>
59119
struct ValueTypeTraits
60120
{
61-
// Set by r-value reference, get by const reference, and release by value. The only types
62-
// that actually support all 3 methods are StringType and ScalarType, everything else
121+
// Set by r-value reference, get by const reference, and release by value. The only types that
122+
// actually support all 3 methods are StringType, IdType, and ScalarType, everything else
63123
// overrides some subset of these types with a template specialization.
64124
using set_type = ValueType&&;
65125
using get_type = const ValueType&;
@@ -106,15 +166,6 @@ struct ValueTypeTraits<FloatType>
106166
using get_type = FloatType;
107167
};
108168

109-
template <>
110-
struct ValueTypeTraits<IdType>
111-
{
112-
// ID values are represented as a Base64 String, so they require conversion.
113-
using set_type = const IdType&;
114-
using get_type = IdType;
115-
using release_type = IdType;
116-
};
117-
118169
// Represent a discriminated union of GraphQL response value types.
119170
struct Value
120171
{
@@ -126,7 +177,7 @@ struct Value
126177
GRAPHQLRESPONSE_EXPORT explicit Value(BooleanType value);
127178
GRAPHQLRESPONSE_EXPORT explicit Value(IntType value);
128179
GRAPHQLRESPONSE_EXPORT explicit Value(FloatType value);
129-
GRAPHQLRESPONSE_EXPORT explicit Value(const IdType& value);
180+
GRAPHQLRESPONSE_EXPORT explicit Value(IdType&& value);
130181

131182
GRAPHQLRESPONSE_EXPORT Value(Value&& other) noexcept;
132183
GRAPHQLRESPONSE_EXPORT explicit Value(const Value& other);
@@ -138,16 +189,22 @@ struct Value
138189

139190
// Comparison
140191
GRAPHQLRESPONSE_EXPORT bool operator==(const Value& rhs) const noexcept;
141-
GRAPHQLRESPONSE_EXPORT bool operator!=(const Value& rhs) const noexcept;
142192

143193
// Check the Type
144194
GRAPHQLRESPONSE_EXPORT Type type() const noexcept;
145195

146-
// JSON doesn't distinguish between Type::String and Type::EnumValue, so if this value comes
147-
// from JSON and it's a string we need to track the fact that it can be interpreted as either.
196+
// JSON doesn't distinguish between Type::String, Type::EnumValue, and Type::ID, so if this
197+
// value comes from JSON and it's a string we need to track the fact that it can be interpreted
198+
// as any of those types.
148199
GRAPHQLRESPONSE_EXPORT Value&& from_json() noexcept;
149200
GRAPHQLRESPONSE_EXPORT bool maybe_enum() const noexcept;
150201

202+
// Input values don't distinguish between Type::String and Type::ID, so if this value comes from
203+
// a string literal input value we need to track that fact that it can be interpreted as either
204+
// of those types.
205+
GRAPHQLRESPONSE_EXPORT Value&& from_input() noexcept;
206+
GRAPHQLRESPONSE_EXPORT bool maybe_id() const noexcept;
207+
151208
// Valid for Type::Map or Type::List
152209
GRAPHQLRESPONSE_EXPORT void reserve(size_t count);
153210
GRAPHQLRESPONSE_EXPORT size_t size() const;
@@ -196,6 +253,7 @@ struct Value
196253

197254
StringType string;
198255
bool from_json = false;
256+
bool from_input = false;
199257
};
200258

201259
// Type::Null
@@ -218,10 +276,12 @@ struct Value
218276
using SharedData = std::shared_ptr<const Value>;
219277

220278
using TypeData = std::variant<MapData, ListType, StringData, NullData, BooleanType, IntType,
221-
FloatType, EnumData, ScalarData, SharedData>;
279+
FloatType, EnumData, IdType, ScalarData, SharedData>;
222280

223281
const TypeData& data() const noexcept;
224282

283+
static Type typeOf(const TypeData& data) noexcept;
284+
225285
TypeData _data;
226286
};
227287

@@ -238,7 +298,7 @@ GRAPHQLRESPONSE_EXPORT void Value::set<FloatType>(FloatType value);
238298
template <>
239299
GRAPHQLRESPONSE_EXPORT void Value::set<ScalarType>(ScalarType&& value);
240300
template <>
241-
GRAPHQLRESPONSE_EXPORT void Value::set<IdType>(const IdType& value);
301+
GRAPHQLRESPONSE_EXPORT void Value::set<IdType>(IdType&& value);
242302
template <>
243303
GRAPHQLRESPONSE_EXPORT const MapType& Value::get<MapType>() const;
244304
template <>
@@ -254,7 +314,7 @@ GRAPHQLRESPONSE_EXPORT FloatType Value::get<FloatType>() const;
254314
template <>
255315
GRAPHQLRESPONSE_EXPORT const ScalarType& Value::get<ScalarType>() const;
256316
template <>
257-
GRAPHQLRESPONSE_EXPORT IdType Value::get<IdType>() const;
317+
GRAPHQLRESPONSE_EXPORT const IdType& Value::get<IdType>() const;
258318
template <>
259319
GRAPHQLRESPONSE_EXPORT MapType Value::release<MapType>();
260320
template <>

0 commit comments

Comments
 (0)