Skip to content

Allow field getters to return a std::shared_ptr<const response::Value> #181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion include/graphqlservice/GraphQLResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ struct Value
GRAPHQLRESPONSE_EXPORT Value(Value&& other) noexcept;
GRAPHQLRESPONSE_EXPORT explicit Value(const Value& other);

GRAPHQLRESPONSE_EXPORT Value(std::shared_ptr<const Value> other) noexcept;

GRAPHQLRESPONSE_EXPORT Value& operator=(Value&& rhs) noexcept;
Value& operator=(const Value& rhs) = delete;

Expand Down Expand Up @@ -213,8 +215,12 @@ struct Value
std::unique_ptr<ScalarType> scalar;
};

using SharedData = std::shared_ptr<const Value>;

using TypeData = std::variant<MapData, ListType, StringData, NullData, BooleanType, IntType,
FloatType, EnumData, ScalarData>;
FloatType, EnumData, ScalarData, SharedData>;

const TypeData& data() const noexcept;

TypeData _data;
};
Expand Down
66 changes: 64 additions & 2 deletions include/graphqlservice/GraphQLService.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,11 @@ class FieldResult

return value.wait_for(0s) != std::future_status::timeout;
}
else if constexpr (std::is_same_v<value_type,
std::shared_ptr<const response::Value>>)
{
return true;
}
},
_value);
}
Expand All @@ -375,7 +380,7 @@ class FieldResult
T await_resume()
{
return std::visit(
[](auto&& value) {
[](auto&& value) -> T {
using value_type = std::decay_t<decltype(value)>;

if constexpr (std::is_same_v<value_type, T>)
Expand All @@ -386,12 +391,34 @@ class FieldResult
{
return value.get();
}
else if constexpr (std::is_same_v<value_type,
std::shared_ptr<const response::Value>>)
{
throw std::logic_error("Cannot await std::shared_ptr<const response::Value>");
}
},
std::move(_value));
}

std::shared_ptr<const response::Value> get_value() noexcept
{
return std::visit(
[](auto&& value) noexcept {
using value_type = std::decay_t<decltype(value)>;
std::shared_ptr<const response::Value> result;

if constexpr (std::is_same_v<value_type, std::shared_ptr<const response::Value>>)
{
result = std::move(value);
}

return result;
},
std::move(_value));
}

private:
std::variant<T, std::future<T>> _value;
std::variant<T, std::future<T>, std::shared_ptr<const response::Value>> _value;
};

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

auto value = result.get_value();

if (value)
{
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
}

co_await params.launch;

auto awaitedResult = co_await ModifiedResult<Object>::convert(
Expand Down Expand Up @@ -738,6 +772,13 @@ struct ModifiedResult
convert(
typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
{
auto value = result.get_value();

if (value)
{
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
}

co_await params.launch;

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

auto value = result.get_value();

if (value)
{
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
}

co_await params.launch;

auto awaitedResult = co_await std::move(result);
Expand All @@ -785,6 +833,13 @@ struct ModifiedResult
static typename std::enable_if_t<TypeModifier::List == Modifier, AwaitableResolver> convert(
typename ResultTraits<Type, Modifier, Other...>::future_type result, ResolverParams params)
{
auto value = result.get_value();

if (value)
{
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
}

std::vector<AwaitableResolver> children;
const auto parentPath = params.errorPath;

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

auto value = result.get_value();

if (value)
{
co_return ResolverResult { response::Value { std::shared_ptr { std::move(value) } } };
}

auto pendingResolver = std::move(resolver);
ResolverResult document;

Expand Down
8 changes: 4 additions & 4 deletions samples/today/TodayMock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,22 @@ namespace graphql::today {
Appointment::Appointment(
response::IdType&& id, std::string&& when, std::string&& subject, bool isNow)
: _id(std::move(id))
, _when(std::move(when))
, _subject(std::move(subject))
, _when(std::make_shared<response::Value>(std::move(when)))
, _subject(std::make_shared<response::Value>(std::move(subject)))
, _isNow(isNow)
{
}

Task::Task(response::IdType&& id, std::string&& title, bool isComplete)
: _id(std::move(id))
, _title(std::move(title))
, _title(std::make_shared<response::Value>(std::move(title)))
, _isComplete(isComplete)
{
}

Folder::Folder(response::IdType&& id, std::string&& name, int unreadCount)
: _id(std::move(id))
, _name(std::move(name))
, _name(std::make_shared<response::Value>(std::move(name)))
, _unreadCount(unreadCount)
{
}
Expand Down
37 changes: 19 additions & 18 deletions samples/today/TodayMock.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@

#include "TodaySchema.h"

#include "QueryObject.h"
#include "AppointmentEdgeObject.h"
#include "AppointmentObject.h"
#include "FolderEdgeObject.h"
#include "FolderObject.h"
#include "MutationObject.h"
#include "SubscriptionObject.h"
#include "NodeObject.h"
#include "PageInfoObject.h"
#include "AppointmentEdgeObject.h"
#include "QueryObject.h"
#include "SubscriptionObject.h"
#include "TaskEdgeObject.h"
#include "FolderEdgeObject.h"
#include "AppointmentObject.h"
#include "TaskObject.h"
#include "FolderObject.h"

#include <atomic>
#include <memory>
#include <stack>

namespace graphql::today {
Expand Down Expand Up @@ -146,14 +147,14 @@ class Appointment
return _id;
}

std::optional<response::Value> getWhen() const noexcept
std::shared_ptr<const response::Value> getWhen() const noexcept
{
return std::make_optional<response::Value>(std::string(_when));
return _when;
}

std::optional<std::string> getSubject() const noexcept
std::shared_ptr<const response::Value> getSubject() const noexcept
{
return std::make_optional<std::string>(_subject);
return _subject;
}

bool getIsNow() const noexcept
Expand All @@ -168,8 +169,8 @@ class Appointment

private:
response::IdType _id;
std::string _when;
std::string _subject;
std::shared_ptr<const response::Value> _when;
std::shared_ptr<const response::Value> _subject;
bool _isNow;
};

Expand Down Expand Up @@ -247,9 +248,9 @@ class Task
return _id;
}

std::optional<std::string> getTitle() const noexcept
std::shared_ptr<const response::Value> getTitle() const noexcept
{
return std::make_optional<std::string>(_title);
return _title;
}

bool getIsComplete() const noexcept
Expand All @@ -259,7 +260,7 @@ class Task

private:
response::IdType _id;
std::string _title;
std::shared_ptr<const response::Value> _title;
bool _isComplete;
TaskState _state = TaskState::New;
};
Expand Down Expand Up @@ -337,9 +338,9 @@ class Folder
return _id;
}

std::optional<std::string> getName() const noexcept
std::shared_ptr<const response::Value> getName() const noexcept
{
return std::make_optional<std::string>(_name);
return _name;
}

int getUnreadCount() const noexcept
Expand All @@ -349,7 +350,7 @@ class Folder

private:
response::IdType _id;
std::string _name;
std::shared_ptr<const response::Value> _name;
int _unreadCount;
};

Expand Down
Loading