inicpp
C++ parser of INI files with schema validation.
option_schema.h
1 #ifndef INICPP_OPTION_SCHEMA_H
2 #define INICPP_OPTION_SCHEMA_H
3 
4 #include <functional>
5 #include <iostream>
6 #include <string>
7 #include <vector>
8 
9 #include "dll.h"
10 #include "exception.h"
11 #include "option.h"
12 #include "types.h"
13 
14 namespace inicpp
15 {
21  {
22  public:
23  virtual ~option_schema_params_base()
24  {
25  }
27  std::string name;
29  item_requirement requirement = item_requirement::mandatory;
31  option_item type = option_item::single;
33  std::string default_value = "";
35  std::string comment = "";
36  };
37 
38 
43  template <typename ArgType> class option_schema_params : public option_schema_params_base
44  {
45  public:
46  virtual ~option_schema_params()
47  {
48  }
53  std::function<bool(ArgType)> validator = nullptr;
54  };
55 
56 
58  class option;
59 
60 
66  class INICPP_API option_schema
67  {
68  private:
70  option_type type_;
72  std::unique_ptr<option_schema_params_base> params_;
73 
74  template <typename ValueType>
75  std::unique_ptr<option_schema_params_base> copy_schema(const std::unique_ptr<option_schema_params_base> &opt)
76  {
78  // call copy constructor of option_schema_params<ValueType>
79  auto new_schema_value = std::make_unique<option_schema_params<ValueType>>(*ptr);
80  return std::move(new_schema_value);
81  }
82 
87  void validate_option_items(option &opt) const;
88 
89  template <typename ValueType>
90  void validate_typed_option_items(const std::vector<ValueType> &items, const std::string &option_name) const
91  {
92  for (const auto &item : items) {
93  option_schema_params<ValueType> *ptr = dynamic_cast<option_schema_params<ValueType> *>(&*params_);
94  if (ptr != nullptr && ptr->validator != nullptr && !ptr->validator(item)) {
95  throw validation_exception("Option '" + option_name + "' - validation failed");
96  }
97  }
98  }
99 
100  void parse_option_items(option &opt) const;
101 
102  template <typename ValueType>
103  std::vector<ValueType> parse_typed_option_items(const std::vector<std::string> &items,
104  std::function<ValueType(const std::string &, const std::string &)> parser,
105  const std::string &option_name) const
106  {
107  std::vector<ValueType> typed_items;
108  for (const auto &item : items) {
109  typed_items.push_back(parser(item, option_name));
110  }
111  return typed_items;
112  }
113 
114  public:
118  option_schema() = delete;
122  option_schema(const option_schema &source);
126  option_schema &operator=(const option_schema &source);
130  option_schema(option_schema &&source);
134  option_schema &operator=(option_schema &&source);
135 
141  template <typename ArgType> option_schema(const option_schema_params<ArgType> &arguments)
142  {
143  type_ = get_option_enum_type<ArgType>();
144  if (type_ == option_type::invalid_e) {
145  throw invalid_type_exception("Invalid schema type");
146  }
147 
148  params_ = std::make_unique<option_schema_params<ArgType>>(arguments);
149  }
150 
155  const std::string &get_name() const;
160  option_type get_type() const;
165  bool is_list() const;
170  const std::string &get_default_value() const;
175  bool is_mandatory() const;
180  const std::string &get_comment() const;
181 
187  void validate_option(option &opt) const;
188 
195  std::ostream &write_additional_info(std::ostream &os) const;
202  INICPP_API friend std::ostream &operator<<(std::ostream &os, const option_schema &opt_schema);
203  };
204 
205  INICPP_API std::ostream &operator<<(std::ostream &os, const option_schema &opt_schema);
206 }
207 
208 #endif
Definition: config.h:15
std::function< bool(ArgType)> validator
Definition: option_schema.h:53
option_schema(const option_schema_params< ArgType > &arguments)