Skip to content

Commit eee1d66

Browse files
committed
fix: split shared types into separate <Prefix>SharedTypes.cpp
1 parent 0e5ded2 commit eee1d66

21 files changed

+2492
-2256
lines changed

cmake/cppgraphqlgen-update-schema-files.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ foreach(OLD_FILE ${OLD_FILES})
5454
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.ixx" AND
5555
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp" AND
5656
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.h" AND
57-
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.ixx")
57+
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.ixx" AND
58+
NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}SharedTypes.cpp")
5859
message(WARNING "Unexpected file in ${SCHEMA_TARGET} GraphQL schema sources: ${OLD_FILE}")
5960
endif()
6061
endif()

include/SchemaGenerator.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ class [[nodiscard("unnecessary construction")]] Generator
4040
[[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept;
4141
[[nodiscard("unnecessary memory copy")]] std::string getSchemaHeaderPath() const noexcept;
4242
[[nodiscard("unnecessary memory copy")]] std::string getSchemaModulePath() const noexcept;
43+
[[nodiscard("unnecessary memory copy")]] std::string getSchemaSourcePath() const noexcept;
4344
[[nodiscard("unnecessary memory copy")]] std::string getSharedTypesHeaderPath() const noexcept;
4445
[[nodiscard("unnecessary memory copy")]] std::string getSharedTypesModulePath() const noexcept;
45-
[[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept;
46+
[[nodiscard("unnecessary memory copy")]] std::string getSharedTypesSourcePath() const noexcept;
4647

4748
[[nodiscard("unnecessary call")]] bool outputSchemaHeader() const noexcept;
4849
[[nodiscard("unnecessary call")]] bool outputSchemaModule() const noexcept;
@@ -62,7 +63,8 @@ class [[nodiscard("unnecessary construction")]] Generator
6263
[[nodiscard("unnecessary memory copy")]] std::string getResolverDeclaration(
6364
const OutputField& outputField) const noexcept;
6465

65-
[[nodiscard("unnecessary call")]] bool outputSource() const noexcept;
66+
[[nodiscard("unnecessary call")]] bool outputSchemaSource() const noexcept;
67+
[[nodiscard("unnecessary call")]] bool outputSharedTypesSource() const noexcept;
6668
void outputInterfaceImplementation(std::ostream& sourceFile, std::string_view cppType) const;
6769
void outputInterfaceIntrospection(
6870
std::ostream& sourceFile, const InterfaceType& interfaceType) const;
@@ -100,9 +102,10 @@ class [[nodiscard("unnecessary construction")]] Generator
100102
const std::string _sourceDir;
101103
const std::string _schemaHeaderPath;
102104
const std::string _schemaModulePath;
105+
const std::string _schemaSourcePath;
103106
const std::string _sharedTypesHeaderPath;
104107
const std::string _sharedTypesModulePath;
105-
const std::string _sourcePath;
108+
const std::string _sharedTypesSourcePath;
106109
};
107110

108111
} // namespace graphql::generator::schema

samples/learn/schema/StarWarsSchema.cpp

Lines changed: 7 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -22,129 +22,7 @@
2222

2323
using namespace std::literals;
2424

25-
namespace graphql {
26-
namespace service {
27-
28-
static const auto s_namesEpisode = learn::getEpisodeNames();
29-
static const auto s_valuesEpisode = learn::getEpisodeValues();
30-
31-
template <>
32-
learn::Episode Argument<learn::Episode>::convert(const response::Value& value)
33-
{
34-
if (!value.maybe_enum())
35-
{
36-
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
37-
}
38-
39-
const auto result = internal::sorted_map_lookup<internal::shorter_or_less>(
40-
s_valuesEpisode,
41-
std::string_view { value.get<std::string>() });
42-
43-
if (!result)
44-
{
45-
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
46-
}
47-
48-
return *result;
49-
}
50-
51-
template <>
52-
service::AwaitableResolver Result<learn::Episode>::convert(service::AwaitableScalar<learn::Episode> result, ResolverParams&& params)
53-
{
54-
return ModifiedResult<learn::Episode>::resolve(std::move(result), std::move(params),
55-
[](learn::Episode value, const ResolverParams&)
56-
{
57-
response::Value resolvedResult(response::Type::EnumValue);
58-
59-
resolvedResult.set<std::string>(std::string { s_namesEpisode[static_cast<std::size_t>(value)] });
60-
61-
return resolvedResult;
62-
});
63-
}
64-
65-
template <>
66-
void Result<learn::Episode>::validateScalar(const response::Value& value)
67-
{
68-
if (!value.maybe_enum())
69-
{
70-
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
71-
}
72-
73-
const auto [itr, itrEnd] = internal::sorted_map_equal_range<internal::shorter_or_less>(
74-
s_valuesEpisode.begin(),
75-
s_valuesEpisode.end(),
76-
std::string_view { value.get<std::string>() });
77-
78-
if (itr == itrEnd)
79-
{
80-
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
81-
}
82-
}
83-
84-
template <>
85-
learn::ReviewInput Argument<learn::ReviewInput>::convert(const response::Value& value)
86-
{
87-
auto valueStars = service::ModifiedArgument<int>::require("stars", value);
88-
auto valueCommentary = service::ModifiedArgument<std::string>::require<service::TypeModifier::Nullable>("commentary", value);
89-
90-
return learn::ReviewInput {
91-
valueStars,
92-
std::move(valueCommentary)
93-
};
94-
}
95-
96-
} // namespace service
97-
98-
namespace learn {
99-
100-
ReviewInput::ReviewInput() noexcept
101-
: stars {}
102-
, commentary {}
103-
{
104-
// Explicit definition to prevent ODR violations when LTO is enabled.
105-
}
106-
107-
ReviewInput::ReviewInput(
108-
int starsArg,
109-
std::optional<std::string> commentaryArg) noexcept
110-
: stars { std::move(starsArg) }
111-
, commentary { std::move(commentaryArg) }
112-
{
113-
}
114-
115-
ReviewInput::ReviewInput(const ReviewInput& other)
116-
: stars { service::ModifiedArgument<int>::duplicate(other.stars) }
117-
, commentary { service::ModifiedArgument<std::string>::duplicate<service::TypeModifier::Nullable>(other.commentary) }
118-
{
119-
}
120-
121-
ReviewInput::ReviewInput(ReviewInput&& other) noexcept
122-
: stars { std::move(other.stars) }
123-
, commentary { std::move(other.commentary) }
124-
{
125-
}
126-
127-
ReviewInput::~ReviewInput()
128-
{
129-
// Explicit definition to prevent ODR violations when LTO is enabled.
130-
}
131-
132-
ReviewInput& ReviewInput::operator=(const ReviewInput& other)
133-
{
134-
ReviewInput value { other };
135-
136-
std::swap(*this, value);
137-
138-
return *this;
139-
}
140-
141-
ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept
142-
{
143-
stars = std::move(other.stars);
144-
commentary = std::move(other.commentary);
145-
146-
return *this;
147-
}
25+
namespace graphql::learn {
14826

14927
Operations::Operations(std::shared_ptr<object::Query> query, std::shared_ptr<object::Mutation> mutation, std::shared_ptr<object::Subscription> subscription)
15028
: service::Request({
@@ -179,10 +57,12 @@ void AddTypesToSchema(const std::shared_ptr<schema::Schema>& schema)
17957
auto typeSubscription = schema::ObjectType::Make(R"gql(Subscription)gql"sv, R"md()md"sv);
18058
schema->AddType(R"gql(Subscription)gql"sv, typeSubscription);
18159

60+
61+
static const auto s_namesEpisode = getEpisodeNames();
18262
typeEpisode->AddEnumValues({
183-
{ service::s_namesEpisode[static_cast<std::size_t>(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt },
184-
{ service::s_namesEpisode[static_cast<std::size_t>(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt },
185-
{ service::s_namesEpisode[static_cast<std::size_t>(learn::Episode::JEDI)], R"md()md"sv, std::nullopt }
63+
{ s_namesEpisode[static_cast<std::size_t>(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt },
64+
{ s_namesEpisode[static_cast<std::size_t>(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt },
65+
{ s_namesEpisode[static_cast<std::size_t>(learn::Episode::JEDI)], R"md()md"sv, std::nullopt }
18666
});
18767

18868
typeReviewInput->AddInputValues({
@@ -220,5 +100,4 @@ std::shared_ptr<schema::Schema> GetSchema()
220100
return schema;
221101
}
222102

223-
} // namespace learn
224-
} // namespace graphql
103+
} // namespace graphql::learn
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
// WARNING! Do not edit this file manually, your changes will be overwritten.
5+
6+
#include "graphqlservice/GraphQLService.h"
7+
8+
#include "StarWarsSharedTypes.h"
9+
10+
#include <algorithm>
11+
#include <array>
12+
#include <cstddef>
13+
#include <functional>
14+
#include <stdexcept>
15+
#include <string_view>
16+
#include <utility>
17+
#include <vector>
18+
19+
using namespace std::literals;
20+
21+
namespace graphql {
22+
namespace service {
23+
24+
static const auto s_namesEpisode = learn::getEpisodeNames();
25+
static const auto s_valuesEpisode = learn::getEpisodeValues();
26+
27+
template <>
28+
learn::Episode Argument<learn::Episode>::convert(const response::Value& value)
29+
{
30+
if (!value.maybe_enum())
31+
{
32+
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
33+
}
34+
35+
const auto result = internal::sorted_map_lookup<internal::shorter_or_less>(
36+
s_valuesEpisode,
37+
std::string_view { value.get<std::string>() });
38+
39+
if (!result)
40+
{
41+
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
42+
}
43+
44+
return *result;
45+
}
46+
47+
template <>
48+
service::AwaitableResolver Result<learn::Episode>::convert(service::AwaitableScalar<learn::Episode> result, ResolverParams&& params)
49+
{
50+
return ModifiedResult<learn::Episode>::resolve(std::move(result), std::move(params),
51+
[](learn::Episode value, const ResolverParams&)
52+
{
53+
response::Value resolvedResult(response::Type::EnumValue);
54+
55+
resolvedResult.set<std::string>(std::string { s_namesEpisode[static_cast<std::size_t>(value)] });
56+
57+
return resolvedResult;
58+
});
59+
}
60+
61+
template <>
62+
void Result<learn::Episode>::validateScalar(const response::Value& value)
63+
{
64+
if (!value.maybe_enum())
65+
{
66+
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
67+
}
68+
69+
const auto [itr, itrEnd] = internal::sorted_map_equal_range<internal::shorter_or_less>(
70+
s_valuesEpisode.begin(),
71+
s_valuesEpisode.end(),
72+
std::string_view { value.get<std::string>() });
73+
74+
if (itr == itrEnd)
75+
{
76+
throw service::schema_exception { { R"ex(not a valid Episode value)ex" } };
77+
}
78+
}
79+
80+
template <>
81+
learn::ReviewInput Argument<learn::ReviewInput>::convert(const response::Value& value)
82+
{
83+
auto valueStars = service::ModifiedArgument<int>::require("stars", value);
84+
auto valueCommentary = service::ModifiedArgument<std::string>::require<service::TypeModifier::Nullable>("commentary", value);
85+
86+
return learn::ReviewInput {
87+
valueStars,
88+
std::move(valueCommentary)
89+
};
90+
}
91+
92+
} // namespace service
93+
94+
namespace learn {
95+
96+
ReviewInput::ReviewInput() noexcept
97+
: stars {}
98+
, commentary {}
99+
{
100+
// Explicit definition to prevent ODR violations when LTO is enabled.
101+
}
102+
103+
ReviewInput::ReviewInput(
104+
int starsArg,
105+
std::optional<std::string> commentaryArg) noexcept
106+
: stars { std::move(starsArg) }
107+
, commentary { std::move(commentaryArg) }
108+
{
109+
}
110+
111+
ReviewInput::ReviewInput(const ReviewInput& other)
112+
: stars { service::ModifiedArgument<int>::duplicate(other.stars) }
113+
, commentary { service::ModifiedArgument<std::string>::duplicate<service::TypeModifier::Nullable>(other.commentary) }
114+
{
115+
}
116+
117+
ReviewInput::ReviewInput(ReviewInput&& other) noexcept
118+
: stars { std::move(other.stars) }
119+
, commentary { std::move(other.commentary) }
120+
{
121+
}
122+
123+
ReviewInput::~ReviewInput()
124+
{
125+
// Explicit definition to prevent ODR violations when LTO is enabled.
126+
}
127+
128+
ReviewInput& ReviewInput::operator=(const ReviewInput& other)
129+
{
130+
ReviewInput value { other };
131+
132+
std::swap(*this, value);
133+
134+
return *this;
135+
}
136+
137+
ReviewInput& ReviewInput::operator=(ReviewInput&& other) noexcept
138+
{
139+
stars = std::move(other.stars);
140+
commentary = std::move(other.commentary);
141+
142+
return *this;
143+
}
144+
145+
} // namespace learn
146+
} // namespace graphql

samples/learn/schema/learn_schema_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
StarWarsSharedTypes.cpp
12
StarWarsSchema.cpp
23
CharacterObject.cpp
34
HumanObject.cpp

0 commit comments

Comments
 (0)