20
20
21
21
#include " graphqlservice/internal/Awaitable.h"
22
22
23
+ #include < cstdint>
24
+ #include < initializer_list>
23
25
#include < memory>
24
26
#include < string>
25
27
#include < string_view>
@@ -31,7 +33,7 @@ namespace graphql::response {
31
33
// GraphQL responses are not technically JSON-specific, although that is probably the most common
32
34
// way of representing them. These are the primitive types that may be represented in GraphQL, as
33
35
// 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
35
37
{
36
38
Map, // JSON Object
37
39
List, // JSON Array
@@ -41,6 +43,7 @@ enum class Type : uint8_t
41
43
Int, // JSON Number
42
44
Float, // JSON Number
43
45
EnumValue, // JSON String
46
+ ID, // JSON String
44
47
Scalar, // JSON any type
45
48
};
46
49
@@ -53,13 +56,70 @@ using BooleanType = bool;
53
56
using IntType = int ;
54
57
using FloatType = double ;
55
58
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
57
117
58
118
template <typename ValueType>
59
119
struct ValueTypeTraits
60
120
{
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
63
123
// overrides some subset of these types with a template specialization.
64
124
using set_type = ValueType&&;
65
125
using get_type = const ValueType&;
@@ -106,15 +166,6 @@ struct ValueTypeTraits<FloatType>
106
166
using get_type = FloatType;
107
167
};
108
168
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
-
118
169
// Represent a discriminated union of GraphQL response value types.
119
170
struct Value
120
171
{
@@ -126,7 +177,7 @@ struct Value
126
177
GRAPHQLRESPONSE_EXPORT explicit Value (BooleanType value);
127
178
GRAPHQLRESPONSE_EXPORT explicit Value (IntType value);
128
179
GRAPHQLRESPONSE_EXPORT explicit Value (FloatType value);
129
- GRAPHQLRESPONSE_EXPORT explicit Value (const IdType& value);
180
+ GRAPHQLRESPONSE_EXPORT explicit Value (IdType& & value);
130
181
131
182
GRAPHQLRESPONSE_EXPORT Value (Value&& other) noexcept ;
132
183
GRAPHQLRESPONSE_EXPORT explicit Value (const Value& other);
@@ -138,16 +189,22 @@ struct Value
138
189
139
190
// Comparison
140
191
GRAPHQLRESPONSE_EXPORT bool operator ==(const Value& rhs) const noexcept ;
141
- GRAPHQLRESPONSE_EXPORT bool operator !=(const Value& rhs) const noexcept ;
142
192
143
193
// Check the Type
144
194
GRAPHQLRESPONSE_EXPORT Type type () const noexcept ;
145
195
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.
148
199
GRAPHQLRESPONSE_EXPORT Value&& from_json() noexcept ;
149
200
GRAPHQLRESPONSE_EXPORT bool maybe_enum () const noexcept ;
150
201
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
+
151
208
// Valid for Type::Map or Type::List
152
209
GRAPHQLRESPONSE_EXPORT void reserve (size_t count);
153
210
GRAPHQLRESPONSE_EXPORT size_t size () const ;
@@ -196,6 +253,7 @@ struct Value
196
253
197
254
StringType string;
198
255
bool from_json = false ;
256
+ bool from_input = false ;
199
257
};
200
258
201
259
// Type::Null
@@ -218,10 +276,12 @@ struct Value
218
276
using SharedData = std::shared_ptr<const Value>;
219
277
220
278
using TypeData = std::variant<MapData, ListType, StringData, NullData, BooleanType, IntType,
221
- FloatType, EnumData, ScalarData, SharedData>;
279
+ FloatType, EnumData, IdType, ScalarData, SharedData>;
222
280
223
281
const TypeData& data () const noexcept ;
224
282
283
+ static Type typeOf (const TypeData& data) noexcept ;
284
+
225
285
TypeData _data;
226
286
};
227
287
@@ -238,7 +298,7 @@ GRAPHQLRESPONSE_EXPORT void Value::set<FloatType>(FloatType value);
238
298
template <>
239
299
GRAPHQLRESPONSE_EXPORT void Value::set<ScalarType>(ScalarType&& value);
240
300
template <>
241
- GRAPHQLRESPONSE_EXPORT void Value::set<IdType>(const IdType& value);
301
+ GRAPHQLRESPONSE_EXPORT void Value::set<IdType>(IdType& & value);
242
302
template <>
243
303
GRAPHQLRESPONSE_EXPORT const MapType& Value::get<MapType>() const ;
244
304
template <>
@@ -254,7 +314,7 @@ GRAPHQLRESPONSE_EXPORT FloatType Value::get<FloatType>() const;
254
314
template <>
255
315
GRAPHQLRESPONSE_EXPORT const ScalarType& Value::get<ScalarType>() const ;
256
316
template <>
257
- GRAPHQLRESPONSE_EXPORT IdType Value::get<IdType>() const ;
317
+ GRAPHQLRESPONSE_EXPORT const IdType& Value::get<IdType>() const ;
258
318
template <>
259
319
GRAPHQLRESPONSE_EXPORT MapType Value::release<MapType>();
260
320
template <>
0 commit comments