Skip to content

Commit 5eeba63

Browse files
authored
Merge pull request #181 from wravery/next
Allow field getters to return a std::shared_ptr<const response::Value>
2 parents fd09323 + 91a5359 commit 5eeba63

File tree

6 files changed

+257
-59
lines changed

6 files changed

+257
-59
lines changed

include/graphqlservice/GraphQLResponse.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ struct Value
131131
GRAPHQLRESPONSE_EXPORT Value(Value&& other) noexcept;
132132
GRAPHQLRESPONSE_EXPORT explicit Value(const Value& other);
133133

134+
GRAPHQLRESPONSE_EXPORT Value(std::shared_ptr<const Value> other) noexcept;
135+
134136
GRAPHQLRESPONSE_EXPORT Value& operator=(Value&& rhs) noexcept;
135137
Value& operator=(const Value& rhs) = delete;
136138

@@ -213,8 +215,12 @@ struct Value
213215
std::unique_ptr<ScalarType> scalar;
214216
};
215217

218+
using SharedData = std::shared_ptr<const Value>;
219+
216220
using TypeData = std::variant<MapData, ListType, StringData, NullData, BooleanType, IntType,
217-
FloatType, EnumData, ScalarData>;
221+
FloatType, EnumData, ScalarData, SharedData>;
222+
223+
const TypeData& data() const noexcept;
218224

219225
TypeData _data;
220226
};

include/graphqlservice/GraphQLService.h

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ class FieldResult
357357

358358
return value.wait_for(0s) != std::future_status::timeout;
359359
}
360+
else if constexpr (std::is_same_v<value_type,
361+
std::shared_ptr<const response::Value>>)
362+
{
363+
return true;
364+
}
360365
},
361366
_value);
362367
}
@@ -375,7 +380,7 @@ class FieldResult
375380
T await_resume()
376381
{
377382
return std::visit(
378-
[](auto&& value) {
383+
[](auto&& value) -> T {
379384
using value_type = std::decay_t<decltype(value)>;
380385

381386
if constexpr (std::is_same_v<value_type, T>)
@@ -386,12 +391,34 @@ class FieldResult
386391
{
387392
return value.get();
388393
}
394+
else if constexpr (std::is_same_v<value_type,
395+
std::shared_ptr<const response::Value>>)
396+
{
397+
throw std::logic_error("Cannot await std::shared_ptr<const response::Value>");
398+
}
399+
},
400+
std::move(_value));
401+
}
402+
403+
std::shared_ptr<const response::Value> get_value() noexcept
404+
{
405+
return std::visit(
406+
[](auto&& value) noexcept {
407+
using value_type = std::decay_t<decltype(value)>;
408+
std::shared_ptr<const response::Value> result;
409+
410+
if constexpr (std::is_same_v<value_type, std::shared_ptr<const response::Value>>)
411+
{
412+
result = std::move(value);
413+
}
414+
415+
return result;
389416
},
390417
std::move(_value));
391418
}
392419

393420
private:
394-
std::variant<T, std::future<T>> _value;
421+
std::variant<T, std::future<T>, std::shared_ptr<const response::Value>> _value;
395422
};
396423

397424
// Fragments are referenced by name and have a single type condition (except for inline
@@ -710,6 +737,13 @@ struct ModifiedResult
710737
static_assert(std::is_same_v<std::shared_ptr<Type>, typename ResultTraits<Type>::type>,
711738
"this is the derived object type");
712739

740+
auto value = result.get_value();
741+
742+
if (value)
743+
{
744+
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
745+
}
746+
713747
co_await params.launch;
714748

715749
auto awaitedResult = co_await ModifiedResult<Object>::convert(
@@ -738,6 +772,13 @@ struct ModifiedResult
738772
convert(
739773
typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
740774
{
775+
auto value = result.get_value();
776+
777+
if (value)
778+
{
779+
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
780+
}
781+
741782
co_await params.launch;
742783

743784
auto awaitedResult = co_await std::move(result);
@@ -765,6 +806,13 @@ struct ModifiedResult
765806
typename ResultTraits<Type, Modifier, Other...>::type>,
766807
"this is the optional version");
767808

809+
auto value = result.get_value();
810+
811+
if (value)
812+
{
813+
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
814+
}
815+
768816
co_await params.launch;
769817

770818
auto awaitedResult = co_await std::move(result);
@@ -785,6 +833,13 @@ struct ModifiedResult
785833
static typename std::enable_if_t<TypeModifier::List == Modifier, AwaitableResolver> convert(
786834
typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
787835
{
836+
auto value = result.get_value();
837+
838+
if (value)
839+
{
840+
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
841+
}
842+
788843
std::vector<AwaitableResolver> children;
789844
const auto parentPath = params.errorPath;
790845

@@ -879,6 +934,13 @@ struct ModifiedResult
879934
static_assert(!std::is_base_of_v<Object, Type>,
880935
"ModfiedResult<Object> needs special handling");
881936

937+
auto value = result.get_value();
938+
939+
if (value)
940+
{
941+
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
942+
}
943+
882944
auto pendingResolver = std::move(resolver);
883945
ResolverResult document;
884946

samples/today/TodayMock.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,22 @@ namespace graphql::today {
2121
Appointment::Appointment(
2222
response::IdType&& id, std::string&& when, std::string&& subject, bool isNow)
2323
: _id(std::move(id))
24-
, _when(std::move(when))
25-
, _subject(std::move(subject))
24+
, _when(std::make_shared<response::Value>(std::move(when)))
25+
, _subject(std::make_shared<response::Value>(std::move(subject)))
2626
, _isNow(isNow)
2727
{
2828
}
2929

3030
Task::Task(response::IdType&& id, std::string&& title, bool isComplete)
3131
: _id(std::move(id))
32-
, _title(std::move(title))
32+
, _title(std::make_shared<response::Value>(std::move(title)))
3333
, _isComplete(isComplete)
3434
{
3535
}
3636

3737
Folder::Folder(response::IdType&& id, std::string&& name, int unreadCount)
3838
: _id(std::move(id))
39-
, _name(std::move(name))
39+
, _name(std::make_shared<response::Value>(std::move(name)))
4040
, _unreadCount(unreadCount)
4141
{
4242
}

samples/today/TodayMock.h

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@
88

99
#include "TodaySchema.h"
1010

11-
#include "QueryObject.h"
11+
#include "AppointmentEdgeObject.h"
12+
#include "AppointmentObject.h"
13+
#include "FolderEdgeObject.h"
14+
#include "FolderObject.h"
1215
#include "MutationObject.h"
13-
#include "SubscriptionObject.h"
1416
#include "NodeObject.h"
1517
#include "PageInfoObject.h"
16-
#include "AppointmentEdgeObject.h"
18+
#include "QueryObject.h"
19+
#include "SubscriptionObject.h"
1720
#include "TaskEdgeObject.h"
18-
#include "FolderEdgeObject.h"
19-
#include "AppointmentObject.h"
2021
#include "TaskObject.h"
21-
#include "FolderObject.h"
2222

2323
#include <atomic>
24+
#include <memory>
2425
#include <stack>
2526

2627
namespace graphql::today {
@@ -146,14 +147,14 @@ class Appointment
146147
return _id;
147148
}
148149

149-
std::optional<response::Value> getWhen() const noexcept
150+
std::shared_ptr<const response::Value> getWhen() const noexcept
150151
{
151-
return std::make_optional<response::Value>(std::string(_when));
152+
return _when;
152153
}
153154

154-
std::optional<std::string> getSubject() const noexcept
155+
std::shared_ptr<const response::Value> getSubject() const noexcept
155156
{
156-
return std::make_optional<std::string>(_subject);
157+
return _subject;
157158
}
158159

159160
bool getIsNow() const noexcept
@@ -168,8 +169,8 @@ class Appointment
168169

169170
private:
170171
response::IdType _id;
171-
std::string _when;
172-
std::string _subject;
172+
std::shared_ptr<const response::Value> _when;
173+
std::shared_ptr<const response::Value> _subject;
173174
bool _isNow;
174175
};
175176

@@ -247,9 +248,9 @@ class Task
247248
return _id;
248249
}
249250

250-
std::optional<std::string> getTitle() const noexcept
251+
std::shared_ptr<const response::Value> getTitle() const noexcept
251252
{
252-
return std::make_optional<std::string>(_title);
253+
return _title;
253254
}
254255

255256
bool getIsComplete() const noexcept
@@ -259,7 +260,7 @@ class Task
259260

260261
private:
261262
response::IdType _id;
262-
std::string _title;
263+
std::shared_ptr<const response::Value> _title;
263264
bool _isComplete;
264265
TaskState _state = TaskState::New;
265266
};
@@ -337,9 +338,9 @@ class Folder
337338
return _id;
338339
}
339340

340-
std::optional<std::string> getName() const noexcept
341+
std::shared_ptr<const response::Value> getName() const noexcept
341342
{
342-
return std::make_optional<std::string>(_name);
343+
return _name;
343344
}
344345

345346
int getUnreadCount() const noexcept
@@ -349,7 +350,7 @@ class Folder
349350

350351
private:
351352
response::IdType _id;
352-
std::string _name;
353+
std::shared_ptr<const response::Value> _name;
353354
int _unreadCount;
354355
};
355356

0 commit comments

Comments
 (0)