$darkmode
schema.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
115 #pragma once
116 #ifndef FABLE_SCHEMA_HPP_
117 #define FABLE_SCHEMA_HPP_
118 
119 #include <chrono> // for duration<>
120 #include <map> // for map<>
121 #include <memory> // for shared_ptr<>
122 #include <string> // for string
123 #include <type_traits> // for enable_if_t<>, is_arithmetic<>, is_enum<>, ...
124 #include <utility> // for move
125 #include <vector> // for vector<>
126 
127 #include <boost/optional.hpp> // for optional<>
128 
129 #include <fable/schema/array.hpp> // for Array<>
130 #include <fable/schema/boolean.hpp> // for Boolean
131 #include <fable/schema/confable.hpp> // for FromConfable
132 #include <fable/schema/const.hpp> // for Const<>
133 #include <fable/schema/duration.hpp> // for Duration<>
134 #include <fable/schema/enum.hpp> // for Enum<>
135 #include <fable/schema/ignore.hpp> // for Ignore
136 #include <fable/schema/interface.hpp> // for Interface, Box
137 #include <fable/schema/json.hpp> // for FromJson<>
138 #include <fable/schema/map.hpp> // for Map<>
139 #include <fable/schema/number.hpp> // for Number<>
140 #include <fable/schema/optional.hpp> // for Optional<>
141 #include <fable/schema/passthru.hpp> // for Passthru
142 #include <fable/schema/path.hpp> // for Path
143 #include <fable/schema/string.hpp> // for String
144 #include <fable/schema/struct.hpp> // for Struct
145 #include <fable/schema/variant.hpp> // for Variant
146 
147 // It is important that this include comes after all the other ones,
148 // so that it has access to ALL the previous definitions.
149 #include <fable/schema/magic.hpp> // for make_prototype, ...
150 
151 namespace fable {
152 
153 // Bring all make_* functions into the fable namespace.
154 using schema::make_const_schema;
155 using schema::make_const_str;
156 using schema::make_prototype;
157 using schema::make_schema;
158 
166 template <typename T>
167 struct schema_type {
168  using type = decltype(make_schema(static_cast<T*>(nullptr), ""));
169 };
170 
178 class Schema : public schema::Interface {
179  public:
180  // Operators
181  Schema(const Schema&) = default;
182  Schema(Schema&&) = default;
183  Schema& operator=(const Schema&) = default;
184 
185  // Struct
186  Schema(std::string&& desc, schema::PropertyList<> props)
187  : impl_(new schema::Struct(std::move(desc), props)) {}
188 
189  Schema(schema::PropertyList<> props) : Schema("", props) {}
190 
191  Schema(std::string&& desc, const Schema& base, schema::PropertyList<> props)
192  : impl_(new schema::Struct(std::move(desc), base, props)) {}
193 
194  Schema(const Schema& base, schema::PropertyList<> props) : Schema("", base, props) {}
195 
196  // Variant
197  Schema(const std::vector<Schema>& xs); // NOLINT(runtime/explicit)
198  Schema(std::string&& desc, const std::vector<Schema>& xs);
199 
200  Schema(schema::BoxList props); // NOLINT(runtime/explicit)
201  Schema(std::string&& desc, schema::BoxList props);
202 
203  Schema(schema::BoxVec&& props); // NOLINT(runtime/explicit)
204  Schema(std::string&& desc, schema::BoxVec&& props);
205 
206  // Interface
207  template <typename T, std::enable_if_t<std::is_base_of<schema::Interface, T>::value, int> = 0>
208  Schema(const T& value) : impl_(value.clone()) {} // NOLINT(runtime/explicit)
209  Schema(schema::Interface* i) : impl_(i) { assert(impl_); } // NOLINT(runtime/explicit)
210  Schema(std::shared_ptr<schema::Interface> i) : impl_(std::move(i)) { // NOLINT(runtime/explicit)
211  assert(impl_);
212  }
213 
214  // Ignore
215  Schema() : impl_(new schema::Ignore("")) {}
216  explicit Schema(std::string&& desc, JsonType t = JsonType::object)
217  : impl_(new schema::Ignore(std::move(desc), t)) {}
218 
219  // Primitives
220  template <typename T>
221  Schema(T* ptr, std::string&& desc) : impl_(make_schema(ptr, std::move(desc)).clone()) {}
222  template <typename T>
223  Schema(T* ptr, const schema::Box& prototype, std::string&& desc)
224  : impl_(make_schema(ptr, prototype, std::move(desc)).clone()) {}
225 
226  // FromJson
227  template <typename T>
228  Schema(T* ptr, JsonType t, std::string&& desc)
229  : impl_(new schema::FromJson<T>(ptr, t, std::move(desc))) {}
230 
231  public: // Special
232  Schema reset_pointer() && {
233  reset_ptr();
234  return std::move(*this);
235  }
236 
237  Json json_schema_qualified() const {
238  Json j = impl_->json_schema();
239  j["$schema"] = "http://json-schema.org/draft-07/schema#";
240  return j;
241  }
242 
243  Json json_schema_qualified(const std::string& id) const {
244  Json j = json_schema_qualified();
245  j["$id"] = id;
246  return j;
247  }
248 
249  friend void to_json(Json& j, const Schema& s) { s.impl_->to_json(j); }
250 
251  public: // Overrides
252  using Interface::to_json;
253  operator schema::Box() const { return schema::Box{impl_}; }
254  Interface* clone() const override { return impl_->clone(); }
255  JsonType type() const override { return impl_->type(); }
256  std::string type_string() const override { return impl_->type_string(); }
257  bool is_required() const override { return impl_->is_required(); }
258  const std::string& description() const override { return impl_->description(); }
259  void set_description(const std::string& s) override { return impl_->set_description(s); }
260  Json usage() const override { return impl_->usage(); }
261  Json json_schema() const override { return impl_->json_schema(); };
262  void validate(const Conf& c) const override { impl_->validate(c); }
263  void to_json(Json& j) const override { impl_->to_json(j); }
264  void from_conf(const Conf& c) override { impl_->from_conf(c); }
265  void reset_ptr() override { impl_->reset_ptr(); }
266 
267  private:
268  std::shared_ptr<schema::Interface> impl_{nullptr};
269 };
270 
271 } // namespace fable
272 
273 #endif // FABLE_SCHEMA_HPP_
Definition: conf.hpp:74
bool is_required() const override
Definition: schema.hpp:257
Definition: ignore.hpp:46
const std::string & description() const override
Definition: schema.hpp:258
Definition: interface.hpp:263
void validate(const Conf &c) const override
Definition: schema.hpp:262
Definition: json.hpp:49
nlohmann::json Json
Definition: json.hpp:62
JsonType type() const override
Definition: schema.hpp:255
void reset_ptr() override
Definition: schema.hpp:265
Json::value_t JsonType
Definition: json.hpp:78
Definition: conf.hpp:70
Definition: interface.hpp:72
Definition: schema.hpp:178
void from_conf(const Conf &c) override
Definition: schema.hpp:264
Definition: struct.hpp:73
Json json_schema() const override
Definition: schema.hpp:261
std::string type_string() const override
Definition: schema.hpp:256
Definition: schema.hpp:167
Interface * clone() const override
Definition: schema.hpp:254
Json usage() const override
Definition: schema.hpp:260
void set_description(const std::string &s) override
Definition: schema.hpp:259
void to_json(Json &j) const override
Definition: schema.hpp:263