$darkmode
path.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 <filesystem> // for path
27 #include <limits> // for numeric_limits<>
28 #include <string> // for string
29 #include <utility> // for move
30 
31 #include <fable/fable_fwd.hpp> // for Environment
32 #include <fable/schema/interface.hpp> // for Base<>
33 #include <fable/utility/path.hpp> // for adl_serializer<>
34 
35 namespace fable::schema {
36 
46 template <typename T>
47 struct is_path : std::false_type {};
48 
49 template <typename T>
50 inline constexpr bool is_path_v = is_path<T>::value;
51 
52 template <>
53 struct is_path<std::filesystem::path> : std::true_type {};
54 
58 enum class PathState {
59  Any,
60  Absent,
61  Exists,
62  Executable,
63  FileExists,
64  DirExists,
65  NotFile,
66  NotDir,
67 };
68 
88 template <typename T>
89 class Path : public Base<Path<T>> {
90  static_assert(is_path_v<T>);
91 
92  public: // Types and Constructors
93  using Type = T;
94  using State = PathState;
95 
96  Path(Type* ptr, std::string desc)
97  : Base<Path<T>>(JsonType::string, std::move(desc)), ptr_(ptr) {}
98 
99  public: // Special
103  [[nodiscard]] State state() const { return req_state_; }
104 
108  Path state(State s) && {
109  req_state_ = s;
110  return std::move(*this);
111  }
112  void set_state(State s) { req_state_ = s; }
113 
114  Path absent() && { return std::move(*this).state(State::Absent); }
115  Path exists() && { return std::move(*this).state(State::Exists); }
116  Path executable() && { return std::move(*this).state(State::Executable); }
117  Path file_exists() && { return std::move(*this).state(State::FileExists); }
118  Path dir_exists() && { return std::move(*this).state(State::DirExists); }
119  Path not_file() && { return std::move(*this).state(State::NotFile); }
120  Path not_dir() && { return std::move(*this).state(State::NotDir); }
121 
122  Path not_empty() && {
123  set_min_length(1);
124  return std::move(*this);
125  }
126 
130  Path absolute() && {
131  req_abs_ = true;
132  return std::move(*this);
133  }
134 
140  [[nodiscard]] bool resolve() const { return resolve_; }
141 
154  Path resolve(bool value) && {
155  resolve_ = value;
156  return std::move(*this);
157  }
158  void set_resolve(bool value) { resolve_ = value; }
159 
160  [[nodiscard]] bool normalize() const { return normalize_; }
161  Path normalize(bool value) && {
162  normalize_ = value;
163  return std::move(*this);
164  }
165  void set_normalize(bool value) { normalize_ = value; }
166 
167  [[nodiscard]] bool interpolate() const { return interpolate_; }
168  void set_interpolate(bool value) { interpolate_ = value; }
169  Path interpolate(bool value) && {
170  interpolate_ = value;
171  return std::move(*this);
172  }
173 
174  [[nodiscard]] Environment* environment() const { return env_; }
175  void set_environment(Environment* env) { env_ = env; }
176  Path environment(Environment* env) && {
177  env_ = env;
178  return std::move(*this);
179  }
180 
181  [[nodiscard]] size_t min_length() const { return min_length_; }
182  void set_min_length(size_t value) { min_length_ = value; }
183  Path min_length(size_t value) && {
184  min_length_ = value;
185  return std::move(*this);
186  }
187 
188  [[nodiscard]] size_t max_length() const { return max_length_; }
189  void set_max_length(size_t value) { max_length_ = value; }
190  Path max_length(size_t value) && {
191  max_length_ = value;
192  return std::move(*this);
193  }
194 
195  [[nodiscard]] const std::string& pattern() const { return pattern_; }
196  void set_pattern(const std::string& value) { pattern_ = value; }
197  Path pattern(const std::string& value) && {
198  pattern_ = value;
199  return std::move(*this);
200  }
201 
202  public: // Overrides
203  [[nodiscard]] Json json_schema() const override;
204  bool validate(const Conf& c, std::optional<SchemaError>& err) const override;
205 
206  using Interface::to_json;
207  void to_json(Json& j) const override {
208  assert(ptr_ != nullptr);
209  j = serialize(*ptr_);
210  }
211 
212  void from_conf(const Conf& c) override {
213  assert(ptr_ != nullptr);
214  *ptr_ = deserialize(c);
215  }
216 
217  [[nodiscard]] Json serialize(const Type& x) const { return x.native(); }
218 
219  [[nodiscard]] Type deserialize(const Conf& c) const;
220 
221  void serialize_into(Json& j, const Type& x) const { j = serialize(x); }
222 
223  void deserialize_into(const Conf& c, Type& x) const { x = deserialize(c); }
224 
225  void reset_ptr() override { ptr_ = nullptr; }
226 
227  private:
228  [[nodiscard]] Type resolve_path(const Conf&, const Type&) const;
229 
230  private:
231  State req_state_{State::Any};
232  bool req_abs_{false};
233  bool resolve_{true};
234  bool normalize_{false};
235  bool interpolate_{false};
236  size_t min_length_{0};
237  size_t max_length_{std::numeric_limits<size_t>::max()};
238  std::string pattern_{};
239  Environment* env_{nullptr};
240  Type* ptr_{nullptr};
241 };
242 
243 template <typename T, std::enable_if_t<is_path_v<T>, bool> = true>
244 inline Path<T> make_schema(T* ptr, std::string desc) {
245  return Path(ptr, std::move(desc));
246 }
247 
248 } // namespace fable::schema
Definition: server_test.cpp:71
Definition: conf.hpp:76
Definition: interface.hpp:398
virtual Json to_json() const
Definition: interface.hpp:254
Definition: path.hpp:89
Path absolute() &&
Definition: path.hpp:130
void to_json(Json &j) const override
Definition: path.hpp:207
bool resolve() const
Definition: path.hpp:140
Path state(State s) &&
Definition: path.hpp:108
void from_conf(const Conf &c) override
Definition: path.hpp:212
bool validate(const Conf &c, std::optional< SchemaError > &err) const override
Definition: path_impl.hpp:89
State state() const
Definition: path.hpp:103
Path resolve(bool value) &&
Definition: path.hpp:154
Json json_schema() const override
Definition: path_impl.hpp:66
void reset_ptr() override
Definition: path.hpp:225
nlohmann::json Json
Definition: fable_fwd.hpp:35
PathState
Definition: path.hpp:58
@ Exists
path does not exist
@ NotDir
path does not exist or is a directory
@ DirExists
path exists and is a file
@ NotFile
path exists and is a directory
@ Absent
any valid path
@ FileExists
path exists in search path or locally and has executable permission
Definition: path.hpp:47