$darkmode
variant.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  */
25 #pragma once
26 
27 #include <string> // for string
28 #include <utility> // for move
29 #include <vector> // for vector<>
30 
31 #include <fable/schema/interface.hpp> // for Interface
32 
33 namespace fable::schema {
34 
35 using BoxVec = std::vector<Box>;
36 using BoxList = std::initializer_list<Box>;
37 
56 class Variant : public Interface {
57  public: // Constructors
58  Variant(std::initializer_list<Box> vec) : Variant("", vec) {}
59  Variant(std::string desc, std::initializer_list<Box> vec)
60  : Variant(std::move(desc), std::vector<Box>(vec)) {}
61 
62  Variant(std::vector<Box>&& vec) : Variant("", std::move(vec)) {} // NOLINT(runtime/explicit)
63  Variant(std::string desc, std::vector<Box>&& vec);
64 
65  public: // Base
66  [[nodiscard]] std::unique_ptr<Interface> clone() const override {
67  return std::make_unique<Variant>(*this);
68  }
69  [[nodiscard]] operator Box() const { return Box{this->clone()}; }
70  [[nodiscard]] JsonType type() const override { return type_; }
71  [[nodiscard]] std::string type_string() const override { return type_string_; }
72  [[nodiscard]] bool is_variant() const override { return true; }
73  [[nodiscard]] Json usage() const override;
74 
75  [[nodiscard]] bool is_required() const override { return required_; }
76  Variant require() && {
77  required_ = true;
78  return std::move(*this);
79  }
80  Variant required(bool value) && {
81  required_ = value;
82  return std::move(*this);
83  }
84 
85  [[nodiscard]] bool has_description() const { return !desc_.empty(); }
86  void set_description(std::string s) override { desc_ = std::move(s); }
87  [[nodiscard]] const std::string& description() const override { return desc_; }
88  Variant description(std::string desc) && {
89  desc_ = std::move(desc);
90  return std::move(*this);
91  }
92 
93  public: // Special
94  Variant unique_match(bool value) && {
95  unique_match_ = value;
96  return std::move(*this);
97  }
98 
99  Variant reset_pointer() && {
100  reset_ptr();
101  return std::move(*this);
102  }
103 
104  public: // Overrides
105  using Interface::to_json;
106  [[nodiscard]] Json json_schema() const override;
107  bool validate(const Conf& c, std::optional<SchemaError>& err) const override {
108  return validate_index(c, err).has_value();
109  }
110  void to_json(Json& j) const override { schemas_[0].to_json(j); }
111  void from_conf(const Conf& c) override {
112  auto index = variant_index(c);
113  schemas_[index].from_conf(c);
114  }
115 
116  // TODO: Implement or explain why we don't need the following methods:
117  // - serialize
118  // - serialize_into
119  // - deserialize
120  // - deserialize_into
121 
122  void reset_ptr() override;
123 
124  private:
125  std::optional<size_t> validate_index(const Conf& c, std::optional<SchemaError>& err) const;
126  [[nodiscard]] size_t variant_index(const Conf& c) const;
127 
128  private:
129  std::string desc_{};
130  std::vector<Box> schemas_;
131  bool required_{false};
132  JsonType type_{JsonType::null};
133  std::string type_string_{};
134  bool unique_match_{false};
135 };
136 
137 inline Variant make_schema(std::initializer_list<Box> vec) { return {vec}; }
138 inline Variant make_schema(std::string desc, std::initializer_list<Box> vec) {
139  return {std::move(desc), std::vector<Box>(vec)};
140 }
141 
142 inline Variant make_schema(std::vector<Box>&& vec) { return {std::move(vec)}; }
143 inline Variant make_schema(std::string desc, std::vector<Box>&& vec) {
144  return {std::move(desc), std::move(vec)};
145 }
146 
147 } // namespace fable::schema
Definition: conf.hpp:76
Definition: interface.hpp:297
Definition: interface.hpp:67
virtual Json to_json() const
Definition: interface.hpp:254
Definition: variant.hpp:56
bool is_variant() const override
Definition: variant.hpp:72
bool validate(const Conf &c, std::optional< SchemaError > &err) const override
Definition: variant.hpp:107
void reset_ptr() override
Definition: variant.cpp:142
const std::string & description() const override
Definition: variant.hpp:87
std::unique_ptr< Interface > clone() const override
Definition: variant.hpp:66
Json usage() const override
Definition: variant.cpp:76
JsonType type() const override
Definition: variant.hpp:70
void to_json(Json &j) const override
Definition: variant.hpp:110
std::string type_string() const override
Definition: variant.hpp:71
bool is_required() const override
Definition: variant.hpp:75
void from_conf(const Conf &c) override
Definition: variant.hpp:111
Json json_schema() const override
Definition: variant.cpp:85
void set_description(std::string s) override
Definition: variant.hpp:86
nlohmann::json Json
Definition: fable_fwd.hpp:35
nlohmann::detail::value_t JsonType
Definition: fable_fwd.hpp:37