$darkmode
struct.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  */
24 #pragma once
25 
26 #include <map> // for map<>
27 #include <memory> // for shared_ptr<>
28 #include <string> // for string
29 #include <type_traits> // for enable_if_t<>, is_same<>
30 #include <utility> // for move, forward<>, pair<>
31 #include <vector> // for vector<>
32 
33 #include <fable/schema/interface.hpp> // for Base<>
34 
35 namespace fable::schema {
36 
53 template <typename S = Box>
54 using PropertyList = std::initializer_list<std::pair<std::string const, S>>;
55 
56 template <typename T, typename S = Box>
57 using enable_if_property_list_t = std::enable_if_t<std::is_same_v<PropertyList<S>, T>>;
58 
70 class Struct : public Base<Struct> {
71  public: // Constructors
72  explicit Struct(std::string desc = "") : Base(JsonType::object, std::move(desc)) {}
73 
74  Struct(std::string desc, PropertyList<Box> props) : Base(JsonType::object, std::move(desc)) {
75  set_properties(props);
76  }
77 
78  Struct(PropertyList<Box> props) : Struct("", props) {} // NOLINT
79 
80  // Inheriting constructors
105  Struct(std::string desc, const Box& base, PropertyList<Box> props)
106  : Struct(*base.template as<Struct>()) {
107  desc_ = std::move(desc);
108  set_properties(props);
109  }
110 
111  Struct(const Box& base, PropertyList<Box> props) : Struct("", base, props) {}
112 
113  public: // Special
119  void set_property(const std::string& key, Box&& s);
120 
121  Struct property(const std::string& key, Box&& s) && {
122  set_property(key, std::move(s));
123  return std::move(*this);
124  }
125 
131  void set_properties(PropertyList<Box> props);
132 
138  void set_properties_from(const Struct& s) { set_properties(s.properties_); }
139 
140  void set_properties_from(const Box& s) { set_properties_from(*s.template as<Struct>()); }
141 
142  template <typename T, typename = enable_if_confable_t<T>>
143  void set_properties_from(const T* x) {
144  set_properties_from(x->schema());
145  }
146 
147  template <typename T>
148  Struct properties_from(const T x) && {
150  return std::move(*this);
151  }
152 
159  void set_require(std::initializer_list<std::string> init);
160  Struct require(std::initializer_list<std::string> init) &&;
161 
170  void set_require_all();
171  Struct require_all() &&;
172 
180  additional_properties_ = v;
181  return std::move(*this);
182  }
183 
184  template <typename S, typename = enable_if_schema_t<S>>
185  void set_additional_properties(const S& s) {
186  additional_properties_ = true;
187  additional_prototype_ = s.clone();
188  additional_prototype_->reset_ptr();
189  }
190 
191  template <typename S, typename = enable_if_schema_t<S>>
192  Struct additional_properties(const S& s) && {
193  set_additional_properties(s);
194  return std::move(*this);
195  }
196 
197  [[nodiscard]] bool additional_properties() const { return additional_properties_; }
198 
199  void reset_ptr() override;
200 
201  public: // Overrides
202  using Interface::to_json;
203  [[nodiscard]] Json usage() const override;
204  [[nodiscard]] Json json_schema() const override;
205  bool validate(const Conf& c, std::optional<SchemaError>& err) const override;
206  void to_json(Json& j) const override;
207  void from_conf(const Conf& c) override;
208 
209  // NOTE: The following methods cannot be implemented because
210  // Struct does not have an associated type:
211  //
212  // Json serialize(const Type&) const;
213  // void serialize_into(Json&, const Type&) const;
214  // Type deserialize(const Conf&) const;
215  // void deserialize_into(const Conf&, Type&) const;
216  //
217  // This means that `Struct` cannot be used as a prototype schema
218  // directly, for example with `optional`. Use `Confable` instead.
219 
220  private:
221  void set_properties(const std::map<std::string, Box>& props);
222 
223  private:
224  std::map<std::string, Box> properties_{};
225  std::vector<std::string> properties_required_{};
226  std::shared_ptr<Interface> additional_prototype_{};
227  bool additional_properties_{false};
228 };
229 
230 template <typename T, typename = enable_if_property_list_t<T>>
231 inline Struct make_schema(T&& props) {
232  return Struct(std::forward<T>(props));
233 }
234 
235 template <typename T, typename = enable_if_property_list_t<T>>
236 inline Struct make_schema(std::string desc, T&& props) {
237  return Struct(std::move(desc), std::forward<T>(props));
238 }
239 
240 template <typename T, typename = enable_if_property_list_t<T>>
241 inline Struct make_schema(std::string desc, const Box& base, T&& props) {
242  return Struct(std::move(desc), base, std::forward<T>(props));
243 }
244 
245 template <typename T, typename = enable_if_property_list_t<T>>
246 inline Struct make_schema(std::string desc, const Struct& base, T&& props) {
247  return Struct(std::move(desc), base, std::forward<T>(props));
248 }
249 
250 } // namespace fable::schema
Definition: interface.hpp:398
Definition: interface.hpp:297
virtual Json to_json() const
Definition: interface.hpp:254
Definition: struct.hpp:70
void set_properties_from(const Struct &s)
Definition: struct.hpp:138
Json json_schema() const override
Definition: struct.cpp:91
void set_property(const std::string &key, Box &&s)
Definition: struct.cpp:31
bool validate(const Conf &c, std::optional< SchemaError > &err) const override
Definition: struct.cpp:111
Struct(std::string desc, const Box &base, PropertyList< Box > props)
Definition: struct.hpp:105
virtual Json to_json() const
Definition: interface.hpp:254
void reset_ptr() override
Definition: struct.cpp:177
void set_require_all()
Definition: struct.cpp:71
void set_require(std::initializer_list< std::string > init)
Definition: struct.cpp:57
Json usage() const override
Definition: struct.cpp:83
void set_properties(PropertyList< Box > props)
Definition: struct.cpp:45
Struct additional_properties(bool v) &&
Definition: struct.hpp:179
void from_conf(const Conf &c) override
Definition: struct.cpp:142
nlohmann::json Json
Definition: fable_fwd.hpp:35