32namespace mcp::protocol {
40template <
typename Struct,
typename Field>
42 const char* wire_name;
43 Field Struct::* pointer;
44 using field_type = Field;
45 using struct_type = Struct;
47 bool absent_as_monostate =
false;
48 bool absent_as_default =
false;
55template <
typename Struct>
57 Json Struct::* pointer;
58 std::vector<std::string> own_keys;
59 using field_type =
Json;
60 using struct_type = Struct;
65template <
typename Struct,
typename Field>
67 const char* wire_name;
68 Field Struct::* pointer;
69 using field_type = Field;
70 using struct_type = Struct;
74template <
typename Struct,
typename Field>
76 Field Struct::* pointer) {
77 return {wire_name, pointer,
nullptr};
81template <
typename Struct,
typename Field>
83 const char* wire_name, Field Struct::* pointer,
84 core::Result<core::Unit> (*validator)(const Field&)) {
85 return {wire_name, pointer, validator};
89template <
typename Struct>
91 std::vector<std::string> own_keys) {
92 return {pointer, std::move(own_keys)};
96template <
typename Struct,
typename Field>
98 const char* wire_name, Field Struct::* pointer) {
99 return {wire_name, pointer};
120template <
typename... Ts>
122 : std::disjunction<std::is_same<Ts, std::monostate>...> {};
133template <
typename Struct,
typename Field>
135 const char* wire_name, Field Struct::* pointer) {
136 static_assert(is_nullable_variant_v<Field>,
137 "nullable_field requires a std::variant containing "
139 return {wire_name, pointer,
nullptr,
true};
144template <
typename Struct,
typename Field>
146 const char* wire_name, Field Struct::* pointer) {
147 return {wire_name, pointer,
nullptr,
false,
true};
151template <
typename T,
typename =
void>
156 T, std::void_t<decltype(std::declval<T>().extensions)>>
157 : std::bool_constant<
158 std::is_same_v<decltype(std::declval<T>().extensions), Json>> {};
168template <
typename T,
typename =
void>
178template <
typename T,
typename =
void>
187template <
typename S,
typename F>
190 keys.push_back(fd.wire_name);
192template <
typename S,
typename F>
195 keys.push_back(fd.wire_name);
198void push_wire_name(std::vector<std::string>&,
const ExtensionsField<S>&) {}
210 static constexpr bool defined =
false;
221 std::vector<std::string> keys;
224 reflect_fields<T>());
233template <
typename T,
typename =
void>
238 : std::bool_constant<Reflect<T>::defined ||
239 detail::has_intrusive_fields_v<T>> {};
254 return T::cxxmcp_fields();
260Json reflect_to_json(
const T& obj);
273template <
typename T,
typename Enable =
void>
275 static void serialize(
Json& json,
const char* key,
const T& value) {
279 static bool deserialize(
const Json& json,
const char* key, T& target) {
280 if (!json.contains(key)) {
283 const auto& val = json.at(key);
284 if constexpr (std::is_same_v<T, bool>) {
285 if (!val.is_boolean()) {
288 }
else if constexpr (std::is_floating_point_v<T>) {
289 if (!val.is_number()) {
292 }
else if constexpr (std::is_integral_v<T>) {
293 if (!val.is_number_integer()) {
297 target = val.get<T>();
305 static void serialize(
Json& json,
const char* key,
const T& value) {
309 static bool deserialize(
const Json& json,
const char* key, T& target) {
310 if (!json.contains(key)) {
313 auto value = reflect_from_json<T>(json.at(key));
317 target = std::move(*value);
328 static void serialize(
Json& json,
const char* key,
const std::string& value) {
332 static bool deserialize(
const Json& json,
const char* key,
333 std::string& target) {
334 if (!json.contains(key)) {
337 if (!json.at(key).is_string()) {
340 target = json.at(key).get<std::string>();
351 static void serialize(
Json& json,
const char* key,
const Json& value) {
352 if (!value.is_null() && !value.empty()) {
357 static bool deserialize(
const Json& json,
const char* key,
Json& target) {
358 if (!json.contains(key)) {
361 target = json.at(key);
368 static void serialize(
Json& json,
const char* key,
IconTheme value) {
372 static bool deserialize(
const Json& json,
const char* key,
374 if (!json.contains(key) || !json.at(key).is_string()) {
378 if (!value.has_value()) {
398 static void serialize(
Json& json,
const char* key,
399 const std::optional<T>& value) {
400 if (value.has_value()) {
405 static bool deserialize(
const Json& json,
const char* key,
406 std::optional<T>& target) {
407 if (!json.contains(key)) {
414 target = std::move(inner);
425 static void serialize(
Json& json,
const char* key,
426 const std::optional<Json>& value) {
427 if (value.has_value() && !value->is_null()) {
432 static bool deserialize(
const Json& json,
const char* key,
433 std::optional<Json>& target) {
434 if (!json.contains(key)) {
437 target = json.at(key);
448 static void serialize(
Json& json,
const char* key,
449 const std::vector<T>& value) {
453 json[key] = Json::array();
454 for (
const auto& item : value) {
455 Json element = Json::object();
457 json[key].push_back(std::move(element[
"_item"]));
461 static bool deserialize(
const Json& json,
const char* key,
462 std::vector<T>& target) {
463 if (!json.contains(key)) {
466 if (!json.at(key).is_array()) {
470 target.reserve(json.at(key).size());
471 for (
const auto& item : json.at(key)) {
474 if constexpr (has_reflect_v<T>) {
475 auto result = reflect_from_json<T>(item);
479 target.push_back(std::move(*result));
482 element = item.get<T>();
483 target.push_back(std::move(element));
496 static void serialize(
Json& json,
const char* key,
497 const std::vector<std::string>& value) {
504 static bool deserialize(
const Json& json,
const char* key,
505 std::vector<std::string>& target) {
506 if (!json.contains(key)) {
509 if (!json.at(key).is_array()) {
512 target.reserve(json.at(key).size());
513 for (
const auto& item : json.at(key)) {
514 if (!item.is_string()) {
517 target.push_back(item.get<std::string>());
529 static void serialize(
Json& json,
const char* key,
530 const std::map<std::string, std::string>& value) {
534 json[key] = Json::object();
535 for (
const auto& [k, v] : value) {
540 static bool deserialize(
const Json& json,
const char* key,
541 std::map<std::string, std::string>& target) {
542 if (!json.contains(key)) {
545 if (!json.at(key).is_object()) {
549 for (
const auto& [k, v] : json.at(key).items()) {
550 if (!v.is_string()) {
553 target[k] = v.get<std::string>();
565 static void serialize(
Json& json,
const char* key,
566 const std::variant<std::monostate, std::int64_t>& val) {
567 if (std::holds_alternative<std::int64_t>(val)) {
568 json[key] = std::get<std::int64_t>(val);
574 static bool deserialize(
const Json& json,
const char* key,
575 std::variant<std::monostate, std::int64_t>& target) {
576 if (!json.contains(key)) {
577 target = std::monostate{};
580 if (json.at(key).is_null()) {
581 target = std::monostate{};
584 if (json.at(key).is_number_integer()) {
585 target = json.at(key).get<std::int64_t>();
598 static void serialize(
Json& json,
const char* key,
599 const std::variant<std::int64_t, std::string>& val) {
600 json[key] = std::visit([](
const auto& v) {
return Json(v); }, val);
603 static bool deserialize(
const Json& json,
const char* key,
604 std::variant<std::int64_t, std::string>& target) {
605 if (!json.contains(key)) {
608 const auto& val = json.at(key);
609 if (val.is_number_integer()) {
610 target = val.get<std::int64_t>();
613 if (val.is_string()) {
614 target = val.get<std::string>();
626template <
typename Struct,
typename Field>
633template <
typename Struct,
typename Field>
638template <
typename Struct>
648template <
typename Struct,
typename Field>
652 const bool present = json.contains(fd.wire_name);
654 if (fd.absent_as_default) {
655 obj.*(fd.pointer) = Field{};
661 if constexpr (is_optional_v<Field>) {
664 if constexpr (is_nullable_variant_v<Field>) {
665 if (fd.absent_as_monostate) {
666 obj.*(fd.pointer) = Field{std::monostate{}};
672 static_cast<int>(ErrorCode::InvalidRequest),
673 "missing required field '" + std::string(fd.wire_name) +
"'",
679 status = mcp::core::unexpected(
680 core::Error{
static_cast<int>(ErrorCode::InvalidRequest),
681 "invalid field '" + std::string(fd.wire_name) +
"'",
685 if (fd.post_validate) {
686 auto validation = fd.post_validate(temp);
688 status = mcp::core::unexpected(validation.error());
692 obj.*(fd.pointer) = std::move(temp);
698template <
typename Struct>
705template <
typename Struct,
typename Field>
709 if constexpr (is_optional_v<Field>) {
730 static_assert(has_reflect_v<T>,
731 "Reflect<T> must be specialized for this type");
732 Json json = Json::object();
735 std::apply([&](
const auto&... fds) { (
serialize_one(json, obj, fds), ...); },
736 reflect_fields<T>());
739 if constexpr (has_extensions_member_v<T>) {
751 static_assert(has_reflect_v<T>,
752 "Reflect<T> must be specialized for this type");
753 if (!json.is_object()) {
754 return mcp::core::unexpected(
755 core::Error{
static_cast<int>(ErrorCode::InvalidRequest),
756 "expected a JSON object",
765 [&](
const auto&... fds) {
766 auto one = [&](
const auto& fd) {
773 reflect_fields<T>());
776 return mcp::core::unexpected(status.error());
780 if constexpr (has_extensions_member_v<T>) {
785 return extract_known_keys<T>();
798#define CXXMCP_REFL_IMPL_1(T, f1) \
800 struct mcp::protocol::Reflect<T> { \
801 static constexpr bool defined = true; \
802 static auto fields() { return std::make_tuple(field(#f1, &T::f1)); } \
805#define CXXMCP_REFL_IMPL_2(T, f1, f2) \
807 struct mcp::protocol::Reflect<T> { \
808 static constexpr bool defined = true; \
809 static auto fields() { \
810 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2)); \
814#define CXXMCP_REFL_IMPL_3(T, f1, f2, f3) \
816 struct mcp::protocol::Reflect<T> { \
817 static constexpr bool defined = true; \
818 static auto fields() { \
819 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
820 field(#f3, &T::f3)); \
824#define CXXMCP_REFL_IMPL_4(T, f1, f2, f3, f4) \
826 struct mcp::protocol::Reflect<T> { \
827 static constexpr bool defined = true; \
828 static auto fields() { \
829 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
830 field(#f3, &T::f3), field(#f4, &T::f4)); \
834#define CXXMCP_REFL_IMPL_5(T, f1, f2, f3, f4, f5) \
836 struct mcp::protocol::Reflect<T> { \
837 static constexpr bool defined = true; \
838 static auto fields() { \
839 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
840 field(#f3, &T::f3), field(#f4, &T::f4), \
841 field(#f5, &T::f5)); \
845#define CXXMCP_REFL_IMPL_6(T, f1, f2, f3, f4, f5, f6) \
847 struct mcp::protocol::Reflect<T> { \
848 static constexpr bool defined = true; \
849 static auto fields() { \
850 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
851 field(#f3, &T::f3), field(#f4, &T::f4), \
852 field(#f5, &T::f5), field(#f6, &T::f6)); \
856#define CXXMCP_REFL_IMPL_7(T, f1, f2, f3, f4, f5, f6, f7) \
858 struct mcp::protocol::Reflect<T> { \
859 static constexpr bool defined = true; \
860 static auto fields() { \
861 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
862 field(#f3, &T::f3), field(#f4, &T::f4), \
863 field(#f5, &T::f5), field(#f6, &T::f6), \
864 field(#f7, &T::f7)); \
868#define CXXMCP_REFL_IMPL_8(T, f1, f2, f3, f4, f5, f6, f7, f8) \
870 struct mcp::protocol::Reflect<T> { \
871 static constexpr bool defined = true; \
872 static auto fields() { \
873 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
874 field(#f3, &T::f3), field(#f4, &T::f4), \
875 field(#f5, &T::f5), field(#f6, &T::f6), \
876 field(#f7, &T::f7), field(#f8, &T::f8)); \
880#define CXXMCP_REFL_IMPL_9(T, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
882 struct mcp::protocol::Reflect<T> { \
883 static constexpr bool defined = true; \
884 static auto fields() { \
885 return std::make_tuple( \
886 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
887 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
888 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9)); \
892#define CXXMCP_REFL_IMPL_10(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
894 struct mcp::protocol::Reflect<T> { \
895 static constexpr bool defined = true; \
896 static auto fields() { \
897 return std::make_tuple(field(#f1, &T::f1), field(#f2, &T::f2), \
898 field(#f3, &T::f3), field(#f4, &T::f4), \
899 field(#f5, &T::f5), field(#f6, &T::f6), \
900 field(#f7, &T::f7), field(#f8, &T::f8), \
901 field(#f9, &T::f9), field(#f10, &T::f10)); \
905#define CXXMCP_REFL_IMPL_11(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \
907 struct mcp::protocol::Reflect<T> { \
908 static constexpr bool defined = true; \
909 static auto fields() { \
910 return std::make_tuple( \
911 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
912 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
913 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9), \
914 field(#f10, &T::f10), field(#f11, &T::f11)); \
918#define CXXMCP_REFL_IMPL_12(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, \
921 struct mcp::protocol::Reflect<T> { \
922 static constexpr bool defined = true; \
923 static auto fields() { \
924 return std::make_tuple( \
925 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
926 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
927 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9), \
928 field(#f10, &T::f10), field(#f11, &T::f11), field(#f12, &T::f12)); \
932#define CXXMCP_REFL_IMPL_13(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, \
935 struct mcp::protocol::Reflect<T> { \
936 static constexpr bool defined = true; \
937 static auto fields() { \
938 return std::make_tuple( \
939 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
940 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
941 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9), \
942 field(#f10, &T::f10), field(#f11, &T::f11), field(#f12, &T::f12), \
943 field(#f13, &T::f13)); \
947#define CXXMCP_REFL_IMPL_14(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, \
950 struct mcp::protocol::Reflect<T> { \
951 static constexpr bool defined = true; \
952 static auto fields() { \
953 return std::make_tuple( \
954 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
955 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
956 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9), \
957 field(#f10, &T::f10), field(#f11, &T::f11), field(#f12, &T::f12), \
958 field(#f13, &T::f13), field(#f14, &T::f14)); \
962#define CXXMCP_REFL_IMPL_15(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, \
963 f12, f13, f14, f15) \
965 struct mcp::protocol::Reflect<T> { \
966 static constexpr bool defined = true; \
967 static auto fields() { \
968 return std::make_tuple( \
969 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
970 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
971 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9), \
972 field(#f10, &T::f10), field(#f11, &T::f11), field(#f12, &T::f12), \
973 field(#f13, &T::f13), field(#f14, &T::f14), field(#f15, &T::f15)); \
977#define CXXMCP_REFL_IMPL_16(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, \
978 f12, f13, f14, f15, f16) \
980 struct mcp::protocol::Reflect<T> { \
981 static constexpr bool defined = true; \
982 static auto fields() { \
983 return std::make_tuple( \
984 field(#f1, &T::f1), field(#f2, &T::f2), field(#f3, &T::f3), \
985 field(#f4, &T::f4), field(#f5, &T::f5), field(#f6, &T::f6), \
986 field(#f7, &T::f7), field(#f8, &T::f8), field(#f9, &T::f9), \
987 field(#f10, &T::f10), field(#f11, &T::f11), field(#f12, &T::f12), \
988 field(#f13, &T::f13), field(#f14, &T::f14), field(#f15, &T::f15), \
989 field(#f16, &T::f16)); \
994#define CXXMCP_REFLECT_CHOOSER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, \
995 _12, _13, _14, _15, _16, NAME, ...) \
997#define CXXMCP_REFLECT_EXPAND(expr) expr
1007#define CXXMCP_REFLECT(Type, ...) \
1008 using ::mcp::protocol::Reflect; \
1009 using ::mcp::protocol::field; \
1010 CXXMCP_REFLECT_EXPAND(CXXMCP_REFLECT_CHOOSER( \
1011 __VA_ARGS__, CXXMCP_REFL_IMPL_16, CXXMCP_REFL_IMPL_15, \
1012 CXXMCP_REFL_IMPL_14, CXXMCP_REFL_IMPL_13, CXXMCP_REFL_IMPL_12, \
1013 CXXMCP_REFL_IMPL_11, CXXMCP_REFL_IMPL_10, CXXMCP_REFL_IMPL_9, \
1014 CXXMCP_REFL_IMPL_8, CXXMCP_REFL_IMPL_7, CXXMCP_REFL_IMPL_6, \
1015 CXXMCP_REFL_IMPL_5, CXXMCP_REFL_IMPL_4, CXXMCP_REFL_IMPL_3, \
1016 CXXMCP_REFL_IMPL_2, CXXMCP_REFL_IMPL_1)(Type, __VA_ARGS__))
1018#define CXXMCP_REFL_SELF_IMPL_1(T, f1) \
1019 static auto cxxmcp_fields() { \
1020 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1)); \
1023#define CXXMCP_REFL_SELF_IMPL_2(T, f1, f2) \
1024 static auto cxxmcp_fields() { \
1025 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1026 ::mcp::protocol::field(#f2, &T::f2)); \
1029#define CXXMCP_REFL_SELF_IMPL_3(T, f1, f2, f3) \
1030 static auto cxxmcp_fields() { \
1031 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1032 ::mcp::protocol::field(#f2, &T::f2), \
1033 ::mcp::protocol::field(#f3, &T::f3)); \
1036#define CXXMCP_REFL_SELF_IMPL_4(T, f1, f2, f3, f4) \
1037 static auto cxxmcp_fields() { \
1038 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1039 ::mcp::protocol::field(#f2, &T::f2), \
1040 ::mcp::protocol::field(#f3, &T::f3), \
1041 ::mcp::protocol::field(#f4, &T::f4)); \
1044#define CXXMCP_REFL_SELF_IMPL_5(T, f1, f2, f3, f4, f5) \
1045 static auto cxxmcp_fields() { \
1046 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1047 ::mcp::protocol::field(#f2, &T::f2), \
1048 ::mcp::protocol::field(#f3, &T::f3), \
1049 ::mcp::protocol::field(#f4, &T::f4), \
1050 ::mcp::protocol::field(#f5, &T::f5)); \
1053#define CXXMCP_REFL_SELF_IMPL_6(T, f1, f2, f3, f4, f5, f6) \
1054 static auto cxxmcp_fields() { \
1055 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1056 ::mcp::protocol::field(#f2, &T::f2), \
1057 ::mcp::protocol::field(#f3, &T::f3), \
1058 ::mcp::protocol::field(#f4, &T::f4), \
1059 ::mcp::protocol::field(#f5, &T::f5), \
1060 ::mcp::protocol::field(#f6, &T::f6)); \
1063#define CXXMCP_REFL_SELF_IMPL_7(T, f1, f2, f3, f4, f5, f6, f7) \
1064 static auto cxxmcp_fields() { \
1065 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1066 ::mcp::protocol::field(#f2, &T::f2), \
1067 ::mcp::protocol::field(#f3, &T::f3), \
1068 ::mcp::protocol::field(#f4, &T::f4), \
1069 ::mcp::protocol::field(#f5, &T::f5), \
1070 ::mcp::protocol::field(#f6, &T::f6), \
1071 ::mcp::protocol::field(#f7, &T::f7)); \
1074#define CXXMCP_REFL_SELF_IMPL_8(T, f1, f2, f3, f4, f5, f6, f7, f8) \
1075 static auto cxxmcp_fields() { \
1076 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1077 ::mcp::protocol::field(#f2, &T::f2), \
1078 ::mcp::protocol::field(#f3, &T::f3), \
1079 ::mcp::protocol::field(#f4, &T::f4), \
1080 ::mcp::protocol::field(#f5, &T::f5), \
1081 ::mcp::protocol::field(#f6, &T::f6), \
1082 ::mcp::protocol::field(#f7, &T::f7), \
1083 ::mcp::protocol::field(#f8, &T::f8)); \
1086#define CXXMCP_REFL_SELF_IMPL_9(T, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
1087 static auto cxxmcp_fields() { \
1088 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1089 ::mcp::protocol::field(#f2, &T::f2), \
1090 ::mcp::protocol::field(#f3, &T::f3), \
1091 ::mcp::protocol::field(#f4, &T::f4), \
1092 ::mcp::protocol::field(#f5, &T::f5), \
1093 ::mcp::protocol::field(#f6, &T::f6), \
1094 ::mcp::protocol::field(#f7, &T::f7), \
1095 ::mcp::protocol::field(#f8, &T::f8), \
1096 ::mcp::protocol::field(#f9, &T::f9)); \
1099#define CXXMCP_REFL_SELF_IMPL_10(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10) \
1100 static auto cxxmcp_fields() { \
1101 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1102 ::mcp::protocol::field(#f2, &T::f2), \
1103 ::mcp::protocol::field(#f3, &T::f3), \
1104 ::mcp::protocol::field(#f4, &T::f4), \
1105 ::mcp::protocol::field(#f5, &T::f5), \
1106 ::mcp::protocol::field(#f6, &T::f6), \
1107 ::mcp::protocol::field(#f7, &T::f7), \
1108 ::mcp::protocol::field(#f8, &T::f8), \
1109 ::mcp::protocol::field(#f9, &T::f9), \
1110 ::mcp::protocol::field(#f10, &T::f10)); \
1113#define CXXMCP_REFL_SELF_IMPL_11(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
1115 static auto cxxmcp_fields() { \
1116 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1117 ::mcp::protocol::field(#f2, &T::f2), \
1118 ::mcp::protocol::field(#f3, &T::f3), \
1119 ::mcp::protocol::field(#f4, &T::f4), \
1120 ::mcp::protocol::field(#f5, &T::f5), \
1121 ::mcp::protocol::field(#f6, &T::f6), \
1122 ::mcp::protocol::field(#f7, &T::f7), \
1123 ::mcp::protocol::field(#f8, &T::f8), \
1124 ::mcp::protocol::field(#f9, &T::f9), \
1125 ::mcp::protocol::field(#f10, &T::f10), \
1126 ::mcp::protocol::field(#f11, &T::f11)); \
1129#define CXXMCP_REFL_SELF_IMPL_12(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
1131 static auto cxxmcp_fields() { \
1132 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1133 ::mcp::protocol::field(#f2, &T::f2), \
1134 ::mcp::protocol::field(#f3, &T::f3), \
1135 ::mcp::protocol::field(#f4, &T::f4), \
1136 ::mcp::protocol::field(#f5, &T::f5), \
1137 ::mcp::protocol::field(#f6, &T::f6), \
1138 ::mcp::protocol::field(#f7, &T::f7), \
1139 ::mcp::protocol::field(#f8, &T::f8), \
1140 ::mcp::protocol::field(#f9, &T::f9), \
1141 ::mcp::protocol::field(#f10, &T::f10), \
1142 ::mcp::protocol::field(#f11, &T::f11), \
1143 ::mcp::protocol::field(#f12, &T::f12)); \
1146#define CXXMCP_REFL_SELF_IMPL_13(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
1148 static auto cxxmcp_fields() { \
1149 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1150 ::mcp::protocol::field(#f2, &T::f2), \
1151 ::mcp::protocol::field(#f3, &T::f3), \
1152 ::mcp::protocol::field(#f4, &T::f4), \
1153 ::mcp::protocol::field(#f5, &T::f5), \
1154 ::mcp::protocol::field(#f6, &T::f6), \
1155 ::mcp::protocol::field(#f7, &T::f7), \
1156 ::mcp::protocol::field(#f8, &T::f8), \
1157 ::mcp::protocol::field(#f9, &T::f9), \
1158 ::mcp::protocol::field(#f10, &T::f10), \
1159 ::mcp::protocol::field(#f11, &T::f11), \
1160 ::mcp::protocol::field(#f12, &T::f12), \
1161 ::mcp::protocol::field(#f13, &T::f13)); \
1164#define CXXMCP_REFL_SELF_IMPL_14(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
1165 f11, f12, f13, f14) \
1166 static auto cxxmcp_fields() { \
1167 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1168 ::mcp::protocol::field(#f2, &T::f2), \
1169 ::mcp::protocol::field(#f3, &T::f3), \
1170 ::mcp::protocol::field(#f4, &T::f4), \
1171 ::mcp::protocol::field(#f5, &T::f5), \
1172 ::mcp::protocol::field(#f6, &T::f6), \
1173 ::mcp::protocol::field(#f7, &T::f7), \
1174 ::mcp::protocol::field(#f8, &T::f8), \
1175 ::mcp::protocol::field(#f9, &T::f9), \
1176 ::mcp::protocol::field(#f10, &T::f10), \
1177 ::mcp::protocol::field(#f11, &T::f11), \
1178 ::mcp::protocol::field(#f12, &T::f12), \
1179 ::mcp::protocol::field(#f13, &T::f13), \
1180 ::mcp::protocol::field(#f14, &T::f14)); \
1183#define CXXMCP_REFL_SELF_IMPL_15(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
1184 f11, f12, f13, f14, f15) \
1185 static auto cxxmcp_fields() { \
1186 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1187 ::mcp::protocol::field(#f2, &T::f2), \
1188 ::mcp::protocol::field(#f3, &T::f3), \
1189 ::mcp::protocol::field(#f4, &T::f4), \
1190 ::mcp::protocol::field(#f5, &T::f5), \
1191 ::mcp::protocol::field(#f6, &T::f6), \
1192 ::mcp::protocol::field(#f7, &T::f7), \
1193 ::mcp::protocol::field(#f8, &T::f8), \
1194 ::mcp::protocol::field(#f9, &T::f9), \
1195 ::mcp::protocol::field(#f10, &T::f10), \
1196 ::mcp::protocol::field(#f11, &T::f11), \
1197 ::mcp::protocol::field(#f12, &T::f12), \
1198 ::mcp::protocol::field(#f13, &T::f13), \
1199 ::mcp::protocol::field(#f14, &T::f14), \
1200 ::mcp::protocol::field(#f15, &T::f15)); \
1203#define CXXMCP_REFL_SELF_IMPL_16(T, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, \
1204 f11, f12, f13, f14, f15, f16) \
1205 static auto cxxmcp_fields() { \
1206 return std::make_tuple(::mcp::protocol::field(#f1, &T::f1), \
1207 ::mcp::protocol::field(#f2, &T::f2), \
1208 ::mcp::protocol::field(#f3, &T::f3), \
1209 ::mcp::protocol::field(#f4, &T::f4), \
1210 ::mcp::protocol::field(#f5, &T::f5), \
1211 ::mcp::protocol::field(#f6, &T::f6), \
1212 ::mcp::protocol::field(#f7, &T::f7), \
1213 ::mcp::protocol::field(#f8, &T::f8), \
1214 ::mcp::protocol::field(#f9, &T::f9), \
1215 ::mcp::protocol::field(#f10, &T::f10), \
1216 ::mcp::protocol::field(#f11, &T::f11), \
1217 ::mcp::protocol::field(#f12, &T::f12), \
1218 ::mcp::protocol::field(#f13, &T::f13), \
1219 ::mcp::protocol::field(#f14, &T::f14), \
1220 ::mcp::protocol::field(#f15, &T::f15), \
1221 ::mcp::protocol::field(#f16, &T::f16)); \
1224#define CXXMCP_REFLECT_SELF_CHOOSER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
1225 _11, _12, _13, _14, _15, _16, NAME, ...) \
1240#define CXXMCP_REFLECT_SELF(Type, ...) \
1241 CXXMCP_REFLECT_EXPAND(CXXMCP_REFLECT_SELF_CHOOSER( \
1242 __VA_ARGS__, CXXMCP_REFL_SELF_IMPL_16, CXXMCP_REFL_SELF_IMPL_15, \
1243 CXXMCP_REFL_SELF_IMPL_14, CXXMCP_REFL_SELF_IMPL_13, \
1244 CXXMCP_REFL_SELF_IMPL_12, CXXMCP_REFL_SELF_IMPL_11, \
1245 CXXMCP_REFL_SELF_IMPL_10, CXXMCP_REFL_SELF_IMPL_9, \
1246 CXXMCP_REFL_SELF_IMPL_8, CXXMCP_REFL_SELF_IMPL_7, \
1247 CXXMCP_REFL_SELF_IMPL_6, CXXMCP_REFL_SELF_IMPL_5, \
1248 CXXMCP_REFL_SELF_IMPL_4, CXXMCP_REFL_SELF_IMPL_3, \
1249 CXXMCP_REFL_SELF_IMPL_2, CXXMCP_REFL_SELF_IMPL_1)(Type, __VA_ARGS__))
1269#define CXXMCP_REFLECT_CHECK(Struct, expected_count) \
1271 std::tuple_size_v< \
1272 decltype(::mcp::protocol::Reflect<Struct>::fields())> == \
1274 "Reflect<" #Struct \
1275 ">::fields() has " \
1276 "a different number of descriptors than expected (" #expected_count \
1277 "). Update the count or add/remove field descriptors.")
void push_wire_name(std::vector< std::string > &keys, const FieldDescriptor< S, F > &fd)
Overloads that extract wire_name from field descriptors.
Definition reflect.hpp:188
Shared JSON, JSON-RPC, error, cancellation, and progress model types.
std::string_view icon_theme_to_string(IconTheme theme) noexcept
Converts an icon theme enum to the lowercase wire value.
Definition types.hpp:259
void append_json_extensions(Json &json, const Json &extensions)
Flattens extension members into a JSON object without overwriting typed fields.
Definition types.hpp:358
IconTheme
Preferred icon variant for clients with light or dark surfaces.
Definition types.hpp:151
std::optional< IconTheme > icon_theme_from_string(std::string_view value) noexcept
Parses a lowercase icon theme wire value.
Definition types.hpp:270
nlohmann::json Json
JSON value type used by all protocol DTOs.
Definition types.hpp:28
Json collect_json_extensions(const Json &json, std::initializer_list< std::string_view > known_keys)
Collects unknown object members so typed DTOs can preserve future protocol fields and vendor extensio...
Definition types.hpp:320
constexpr FieldDescriptor< Struct, Field > field(const char *wire_name, Field Struct::*pointer)
Creates a FieldDescriptor with wire name and pointer-to-member.
Definition reflect.hpp:75
std::vector< std::string > extract_known_keys()
Extracts known wire names from the fields() tuple at runtime.
Definition reflect.hpp:220
constexpr FieldDescriptor< Struct, Field > defaulted_field(const char *wire_name, Field Struct::*pointer)
Creates a FieldDescriptor whose missing wire value keeps the C++ default value.
Definition reflect.hpp:145
constexpr FieldDescriptor< Struct, Field > nullable_field(const char *wire_name, Field Struct::*pointer)
Creates a FieldDescriptor whose missing wire value maps to std::monostate.
Definition reflect.hpp:134
ExtensionsField< Struct > extensions_field(Json Struct::*pointer, std::vector< std::string > own_keys)
Creates an ExtensionsField descriptor.
Definition reflect.hpp:90
auto reflect_fields()
Returns the field descriptors for a reflectable type.
Definition reflect.hpp:250
void serialize_one(Json &json, const Struct &obj, const FieldDescriptor< Struct, Field > &fd)
Serializes a single field into the JSON object.
Definition reflect.hpp:627
constexpr DeserializeOnlyField< Struct, Field > deserialize_only(const char *wire_name, Field Struct::*pointer)
Creates a DeserializeOnlyField descriptor.
Definition reflect.hpp:97
Json reflect_to_json(const T &obj)
Serializes a DTO to JSON using its Reflect<T> trait.
Definition reflect.hpp:729
constexpr FieldDescriptor< Struct, Field > validated_field(const char *wire_name, Field Struct::*pointer, core::Result< core::Unit >(*validator)(const Field &))
Creates a FieldDescriptor with a post-deserialization validator.
Definition reflect.hpp:82
bool deserialize_one(const Json &json, Struct &obj, const FieldDescriptor< Struct, Field > &fd, core::Result< core::Unit > &status)
Deserializes a single field from the JSON object.
Definition reflect.hpp:649
core::Result< T > reflect_from_json(const Json &json)
Deserializes a DTO from JSON using its Reflect<T> trait.
Definition reflect.hpp:750
Shared result and error primitives used by the public cxxmcp SDK.
std::monostate Unit
Success value for operations that only need to report failure.
Definition result.hpp:55
tl::expected< T, Error > Result
Alias for the SDK result type.
Definition result.hpp:64
Structured error returned by fallible SDK operations.
Definition result.hpp:35
Tag-only field descriptor for fields that are populated during deserialization only (e....
Definition reflect.hpp:66
Tag-only field descriptor for the extensions member.
Definition reflect.hpp:56
Describes a single DTO field: its JSON wire name, pointer-to-member, and optional post-deserializatio...
Definition reflect.hpp:41
Type-specific serialization and deserialization logic.
Definition reflect.hpp:274
Primary template.
Definition reflect.hpp:209
Definition reflect.hpp:169
Definition reflect.hpp:179
Detects whether a type has an extensions member of type Json.
Definition reflect.hpp:152
Detects whether Reflect<T> is specialized for a given type.
Definition reflect.hpp:234
Detects std::variant containing std::monostate (nullable on wire).
Definition reflect.hpp:118
Detects std::optional<T>.
Definition reflect.hpp:108