See More

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. #include "graphqlservice/GraphQLClient.h" using namespace std::literals; namespace graphql::client { ErrorLocation parseServiceErrorLocation(response::Value&& location) { ErrorLocation result; if (location.type() == response::Type::Map) { auto members = location.release<:maptype>(); for (auto& member : members) { if (member.first == "line"sv) { if (member.second.type() == response::Type::Int) { result.line = static_cast(member.second.get()); } continue; } if (member.first == "column"sv) { if (member.second.type() == response::Type::Int) { result.column = static_cast(member.second.get()); } continue; } } } return result; } ErrorPathSegment parseServiceErrorPathSegment(response::Value&& segment) { ErrorPathSegment result { int {} }; switch (segment.type()) { case response::Type::Int: result = segment.get(); break; case response::Type::String: result = segment.release<:string>(); break; default: break; } return result; } Error parseServiceError(response::Value&& error) { Error result; if (error.type() == response::Type::Map) { auto members = error.release<:maptype>(); for (auto& member : members) { if (member.first == "message"sv) { if (member.second.type() == response::Type::String) { result.message = member.second.release<:string>(); } continue; } if (member.first == "locations"sv) { if (member.second.type() == response::Type::List) { auto locations = member.second.release<:listtype>(); result.locations.reserve(locations.size()); std::transform(locations.begin(), locations.end(), std::back_inserter(result.locations), [](response::Value& location) { return parseServiceErrorLocation(std::move(location)); }); } continue; } if (member.first == "path"sv) { if (member.second.type() == response::Type::List) { auto segments = member.second.release<:listtype>(); result.path.reserve(segments.size()); std::transform(segments.begin(), segments.end(), std::back_inserter(result.path), [](response::Value& segment) { return parseServiceErrorPathSegment(std::move(segment)); }); } continue; } } } return result; } ServiceResponse parseServiceResponse(response::Value response) { ServiceResponse result; if (response.type() == response::Type::Map) { auto members = response.release<:maptype>(); for (auto& member : members) { if (member.first == "data"sv) { // The generated client code can parse this. result.data = std::move(member.second); continue; } if (member.first == "errors"sv) { if (member.second.type() == response::Type::List) { auto errors = member.second.release<:listtype>(); result.errors.reserve(errors.size()); std::transform(errors.begin(), errors.end(), std::back_inserter(result.errors), [](response::Value& error) { return parseServiceError(std::move(error)); }); } continue; } } } return result; } template <> response::Value Variable::serialize(int&& value) { return response::Value { value }; } template <> response::Value Variable::serialize(double&& value) { return response::Value { value }; } template <> response::Value Variable<:string>::serialize(std::string&& value) { return response::Value { std::move(value) }; } template <> response::Value Variable::serialize(bool&& value) { return response::Value { value }; } template <> response::Value Variable<:value>::serialize(response::Value&& value) { return response::Value { std::move(value) }; } template <> response::Value Variable<:idtype>::serialize(response::IdType&& value) { return response::Value { std::move(value) }; } template <> int Response::parse(response::Value&& value) { if (value.type() != response::Type::Int) { throw std::logic_error { "not an integer" }; } return value.get(); } template <> double Response::parse(response::Value&& value) { if (value.type() != response::Type::Float && value.type() != response::Type::Int) { throw std::logic_error { "not a float" }; } return value.get(); } template <> std::string Response<:string>::parse(response::Value&& value) { if (value.type() != response::Type::String) { throw std::logic_error { "not a string" }; } return value.release<:string>(); } template <> bool Response::parse(response::Value&& value) { if (value.type() != response::Type::Boolean) { throw std::logic_error { "not a boolean" }; } return value.get(); } template <> response::Value Response<:value>::parse(response::Value&& value) { return { std::move(value) }; } template <> response::IdType Response<:idtype>::parse(response::Value&& value) { if (!value.maybe_id()) { throw std::logic_error { "not an ID" }; } return value.release<:idtype>(); } } // namespace graphql::client