C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
json.hpp
1/*
2 * Copyright (c) 2024 The RefValue Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include "../common_types.hpp"
26#include "../runtime/struct.hpp"
27
28#include <type_traits>
29#include <unordered_set>
30
31namespace essence::meta::detail {
32 template <typename T>
33 concept has_json_serialization_config = std::is_class_v<T> && requires {
34 typename T::json_serialization;
35 requires std::is_enum_v<typename T::json_serialization>;
36 };
37
38 template <typename T>
39 concept has_json_omission_config = std::is_class_v<T> && requires {
40 typename T::json_omission;
41 requires std::is_class_v<typename T::json_omission>;
42 };
43
44 template <typename T>
45 concept has_snake_case = std::is_enum_v<T> && requires { T::snake_case; };
46
47 template <typename T>
48 concept has_camel_case = std::is_enum_v<T> && requires { T::camel_case; };
49
50 template <typename T>
51 concept has_pascal_case = std::is_enum_v<T> && requires { T::pascal_case; };
52
53 template <typename T>
54 concept has_enum_to_string = std::is_enum_v<T> && requires { T::enum_to_string; };
55
56 template <typename T>
59
60 template <typename>
61 consteval auto get_naming_convention_by_enum() noexcept {
62 return naming_convention::snake_case;
63 }
64
65 template <has_snake_case>
66 consteval auto get_naming_convention_by_enum() noexcept {
67 return naming_convention::snake_case;
68 }
69
70 template <has_camel_case>
71 consteval auto get_naming_convention_by_enum() noexcept {
72 return naming_convention::camel_case;
73 }
74
75 template <has_pascal_case>
76 consteval auto get_naming_convention_by_enum() noexcept {
77 return naming_convention::pascal_case;
78 }
79
80 template <typename T>
81 requires std::is_class_v<T>
82 consteval naming_convention get_json_naming_convention() noexcept {
83 if constexpr (has_json_serialization_config<T>) {
84 return get_naming_convention_by_enum<typename T::json_serialization>();
85 } else {
86 return naming_convention::snake_case;
87 }
88 }
89
90 template <typename T>
91 requires std::is_class_v<T>
92 bool check_json_omitted(std::string_view name) {
93 if constexpr (has_json_omission_config<T>) {
94 static const auto mapping = [] {
95 std::unordered_set<std::string_view> result;
96
97 for (auto&& item : runtime::get_data_member_names<typename T::json_omission>()) {
98 result.emplace(item);
99 }
100
101 return result;
102 }();
103
104 return mapping.contains(name);
105 } else {
106 return false;
107 }
108 }
109} // namespace essence::meta::detail