module.h
Go to the documentation of this file.
1 #ifndef GARLIC_MODULE_H
2 #define GARLIC_MODULE_H
3 
9 #include <unordered_map>
10 
11 #include "constraints.h"
12 #include "error.h"
13 #include "utility.h"
14 
15 
16 namespace garlic {
17 
39  class Module {
40  public:
41  template <typename Key, typename Value> using table = std::unordered_map<Key, Value>;
42  using model_type = Model;
43  using model_pointer = std::shared_ptr<model_type>;
44  using field_type = Field;
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;
51 
52  constexpr static auto kDefaultFieldTableSize = 16;
53 
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)},
66  };
67  fields_ = static_map;
68  }
69 
75  tl::expected<void, std::error_code>
76  add_model(model_pointer model) noexcept {
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>();
81  }
82 
89  tl::expected<void, std::error_code>
90  add_field(text&& alias, field_pointer field) noexcept {
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>();
95  }
96 
102  inline tl::expected<void, std::error_code>
103  add_field(field_pointer field) noexcept {
104  return add_field(field->name().view(), field);
105  }
106 
111  model_pointer get_model(const text& name) const noexcept {
112  if (auto it = models_.find(name); it != models_.end()) return it->second;
113  return nullptr;
114  }
115 
119  template<typename Callable>
120  void get_model(const text& name, Callable&& cb) const noexcept {
121  if (auto it = models_.find(name); it != models_.end()) cb(it->second);
122  }
123 
125  inline const_model_iterator begin_models() const { return models_.begin(); }
126 
128  inline const_model_iterator end_models() const { return models_.end(); }
129 
131  inline const_model_iterator find_model(const text& name) const { return models_.find(name); }
132 
134  field_pointer get_field(const text& name) const noexcept {
135  if (auto it = fields_.find(name); it != fields_.end()) return it->second;
136  return nullptr;
137  }
138 
140  template<typename Callable>
141  void get_field(const text& name, Callable&& cb) const noexcept {
142  if (auto it = fields_.find(name); it != fields_.end()) cb(it->second);
143  }
144 
146  inline const_field_iterator begin_fields() const { return fields_.begin(); }
147 
149  inline const_field_iterator end_fields() const { return fields_.end(); }
150 
152  inline const_field_iterator find_field(const text& name) const { return fields_.find(name); }
153 
154  private:
155  template<typename ConstraintTag, typename... Args>
156  static inline field_pointer make_field(text&& name, Args&&... args) noexcept {
157  sequence<Constraint> constraints(1);
158  constraints.push_back(make_constraint<ConstraintTag>(std::forward<Args>(args)...));
159  return std::make_shared<field_type>(Field::Properties {
160  .annotations = {},
161  .constraints = std::move(constraints),
162  .name = std::move(name),
163  .ignore_details = false
164  });
165  }
166 
167  model_table models_;
168  field_table fields_;
169  };
170 }
171 
172 
173 #endif /* end of include guard: GARLIC_MODULE_H */
garlic::Constraint
Smallest unit of data validation.
Definition: constraints.h:275
garlic::Module::get_model
model_pointer get_model(const text &name) const noexcept
Definition: module.h:111
garlic::basic_text< char >
garlic::Module::end_models
const_model_iterator end_models() const
Definition: module.h:128
garlic::Module::find_model
const_model_iterator find_model(const text &name) const
Definition: module.h:131
garlic::Module::get_field
void get_field(const text &name, Callable &&cb) const noexcept
Calls the callable function with a shared pointer to the field, if found.
Definition: module.h:141
garlic::Module
A Module is a repository of models, fields and constraints.
Definition: module.h:39
utility.h
This file contains various functions and classes to work with layers like getting or resolving using ...
garlic::Module::begin_fields
const_field_iterator begin_fields() const
Definition: module.h:146
garlic::Module::add_model
tl::expected< void, std::error_code > add_model(model_pointer model) noexcept
Definition: module.h:76
garlic::Module::begin_models
const_model_iterator begin_models() const
Definition: module.h:125
garlic::Module::Module
Module()
Definition: module.h:57
garlic::Module::end_fields
const_field_iterator end_fields() const
Definition: module.h:149
garlic::Module::get_field
field_pointer get_field(const text &name) const noexcept
Definition: module.h:134
garlic::Module::add_field
tl::expected< void, std::error_code > add_field(text &&alias, field_pointer field) noexcept
Definition: module.h:90
garlic::Model
An object to describe a Model.
Definition: constraints.h:1157
garlic::Module::find_field
const_field_iterator find_field(const text &name) const
Definition: module.h:152
garlic::sequence
A container to store a list of items, similar to std::vector but far more limited.
Definition: containers.h:207
garlic::Field
A named group of Constraint elements.
Definition: constraints.h:1047
garlic::Module::get_model
void get_model(const text &name, Callable &&cb) const noexcept
Definition: module.h:120
garlic::Module::add_field
tl::expected< void, std::error_code > add_field(field_pointer field) noexcept
Definition: module.h:103