$darkmode
enum.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 #ifndef FABLE_SCHEMA_ENUM_HPP_
26 #define FABLE_SCHEMA_ENUM_HPP_
27 
28 #include <map> // for map<>
29 #include <string> // for string
30 #include <type_traits> // for enable_if_t<>, is_enum<>
31 #include <utility> // for move, make_pair
32 #include <vector> // for vector<>
33 
34 #include <fable/enum.hpp>
35 #include <fable/schema/interface.hpp> // for Base<>
36 
37 namespace fable {
38 namespace schema {
39 
40 template <typename T>
41 class Enum : public Base<Enum<T>> {
42  public: // Types and Constructors
43  using Type = T;
44 
45  Enum(Type* ptr, std::string&& desc)
46  : Base<Enum<T>>(JsonType::string, std::move(desc))
47  , mapping_to_(enum_serialization<T>())
48  , mapping_from_(enum_deserialization<T>())
49  , ptr_(ptr) {
50  keys_.reserve(mapping_to_.size());
51  for (auto const& kv : mapping_to_) {
52  keys_.emplace_back(kv.second);
53  }
54  }
55 
56  public: // Special
57  const std::vector<std::string>& keys() const { return keys_; }
58 
59  public: // Overrides
60  Json json_schema() const override {
61  Json j{
62  {"type", this->type_string()},
63  {"enum", keys_},
64  };
65  this->augment_schema(j);
66  return j;
67  }
68 
69  void validate(const Conf& c) const override {
70  std::string s = c.get<std::string>();
71  if (mapping_from_.count(s) == 0) {
72  this->throw_error(c, "invalid value for enum: {}", s);
73  }
74  }
75 
76  using Interface::to_json;
77  void to_json(Json& j) const override {
78  assert(ptr_ != nullptr);
79  j = serialize(*ptr_);
80  }
81 
82  void from_conf(const Conf& c) override {
83  assert(ptr_ != nullptr);
84  *ptr_ = deserialize(c);
85  }
86 
87  Json serialize(const Type& x) const { return mapping_to_.at(x); }
88 
89  Type deserialize(const Conf& c) const {
90  auto s = c.get<std::string>();
91  try {
92  return mapping_from_.at(s);
93  } catch (std::out_of_range& e) {
94  this->throw_error(c, "invalid value for enum: {}", s);
95  }
96  }
97 
98  void reset_ptr() override { ptr_ = nullptr; }
99 
100  private:
101  const std::map<T, std::string>& mapping_to_;
102  const std::map<std::string, T>& mapping_from_;
103  std::vector<std::string> keys_;
104  Type* ptr_{nullptr};
105 };
106 
107 template <typename T, std::enable_if_t<std::is_enum<T>::value, int> = 0>
108 inline Enum<T> make_schema(T* ptr, std::string&& desc) {
109  return Enum<T>(ptr, std::move(desc));
110 }
111 
112 } // namespace schema
113 } // namespace fable
114 
115 #endif // FABLE_SCHEMA_ENUM_HPP_
Definition: conf.hpp:74
Json json_schema() const override
Definition: enum.hpp:60
void reset_ptr() override
Definition: enum.hpp:98
T get() const
Definition: conf.hpp:164
void from_conf(const Conf &c) override
Definition: enum.hpp:82
nlohmann::json Json
Definition: json.hpp:62
void to_json(Json &j) const override
Definition: enum.hpp:77
Definition: conf.hpp:70
Definition: enum.hpp:41
virtual Json to_json() const
Definition: interface.hpp:220
void validate(const Conf &c) const override
Definition: enum.hpp:69
Definition: interface.hpp:354
std::string type_string() const override
Definition: interface.hpp:366