1 #ifndef GARLIC_MODULE_H
2 #define GARLIC_MODULE_H
9 #include <unordered_map>
11 #include "constraints.h"
41 template <
typename Key,
typename Value>
using table = std::unordered_map<Key, Value>;
43 using model_pointer = std::shared_ptr<model_type>;
45 using field_pointer = std::shared_ptr<field_type>;
46 using model_table = table<text, model_pointer>;
47 using field_table = table<text, field_pointer>;
49 using const_model_iterator =
typename model_table::const_iterator;
50 using const_field_iterator =
typename field_table::const_iterator;
52 constexpr
static auto kDefaultFieldTableSize = 16;
57 Module() : fields_(kDefaultFieldTableSize) {
58 static table<text, field_pointer> static_map = {
59 {
"string", this->make_field<type_tag>(
"StringField", TypeFlag::String)},
60 {
"integer", this->make_field<type_tag>(
"IntegerField", TypeFlag::Integer)},
61 {
"double", this->make_field<type_tag>(
"DoubleField", TypeFlag::Double)},
62 {
"list", this->make_field<type_tag>(
"ListField", TypeFlag::List)},
63 {
"object", this->make_field<type_tag>(
"ObjectField", TypeFlag::Object)},
64 {
"bool", this->make_field<type_tag>(
"BooleanField", TypeFlag::Boolean)},
65 {
"null", this->make_field<type_tag>(
"BooleanField", TypeFlag::Null)},
75 tl::expected<void, std::error_code>
77 if (
auto it = models_.find(model->name()); it != models_.end())
78 return tl::make_unexpected(GarlicError::Redefinition);
79 models_.emplace(model->name().view(), std::move(model));
80 return tl::expected<void, std::error_code>();
89 tl::expected<void, std::error_code>
91 if (
auto it = fields_.find(alias); it != fields_.end())
92 return tl::make_unexpected(GarlicError::Redefinition);
93 fields_.emplace(std::move(alias), std::move(field));
94 return tl::expected<void, std::error_code>();
102 inline tl::expected<void, std::error_code>
104 return add_field(field->name().view(), field);
112 if (
auto it = models_.find(name); it != models_.end())
return it->second;
119 template<
typename Callable>
121 if (
auto it = models_.find(name); it != models_.end()) cb(it->second);
125 inline const_model_iterator
begin_models()
const {
return models_.begin(); }
128 inline const_model_iterator
end_models()
const {
return models_.end(); }
131 inline const_model_iterator
find_model(
const text& name)
const {
return models_.find(name); }
135 if (
auto it = fields_.find(name); it != fields_.end())
return it->second;
140 template<
typename Callable>
142 if (
auto it = fields_.find(name); it != fields_.end()) cb(it->second);
146 inline const_field_iterator
begin_fields()
const {
return fields_.begin(); }
149 inline const_field_iterator
end_fields()
const {
return fields_.end(); }
152 inline const_field_iterator
find_field(
const text& name)
const {
return fields_.find(name); }
155 template<
typename ConstraintTag,
typename... Args>
156 static inline field_pointer make_field(
text&& name, Args&&... args) noexcept {
158 constraints.push_back(make_constraint<ConstraintTag>(std::forward<Args>(args)...));
159 return std::make_shared<field_type>(Field::Properties {
161 .constraints = std::move(constraints),
162 .name = std::move(name),
163 .ignore_details =
false