$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) : Base<Path<T>>(JsonType::string, std::move(desc)), ptr_(ptr) {}
97 
98  public: // Special
102  [[nodiscard]] State state() const { return req_state_; }
103 
104  void set_state(State s) { req_state_ = s; }
105 
109  [[nodiscard]] Path state(State s) && {
110  req_state_ = s;
111  return std::move(*this);
112  }
113 
114  [[nodiscard]] Path absent() && { return std::move(*this).state(State::Absent); }
115  [[nodiscard]] Path exists() && { return std::move(*this).state(State::Exists); }
116  [[nodiscard]] Path executable() && { return std::move(*this).state(State::Executable); }
117  [[nodiscard]] Path file_exists() && { return std::move(*this).state(State::FileExists); }
118  [[nodiscard]] Path dir_exists() && { return std::move(*this).state(State::DirExists); }
119  [[nodiscard]] Path not_file() && { return std::move(*this).state(State::NotFile); }
120  [[nodiscard]] Path not_dir() && { return std::move(*this).state(State::NotDir); }
121 
122  [[nodiscard]] Path not_empty() && {
123  set_min_length(1);
124  return std::move(*this);
125  }
126 
127  [[nodiscard]] bool absolute() const {
128  return req_abs_;
129  }
130 
131  void set_absolute(bool value) {
132  req_abs_ = value;
133  }
134 
138  [[nodiscard]] Path absolute(bool value) && {
139  req_abs_ = value;
140  return std::move(*this);
141  }
142 
143 
144 
150  [[nodiscard]] bool resolve() const { return resolve_; }
151 
152  void set_resolve(bool value) { resolve_ = value; }
153 
166  [[nodiscard]] Path resolve(bool value) && {
167  resolve_ = value;
168  return std::move(*this);
169  }
170 
171  [[nodiscard]] bool normalize() const { return normalize_; }
172  void set_normalize(bool value) { normalize_ = value; }
173  [[nodiscard]] Path normalize(bool value) && {
174  normalize_ = value;
175  return std::move(*this);
176  }
177 
178  [[nodiscard]] bool interpolate() const { return interpolate_; }
179  void set_interpolate(bool value) { interpolate_ = value; }
180  [[nodiscard]] Path interpolate(bool value) && {
181  interpolate_ = value;
182  return std::move(*this);
183  }
184 
185  [[nodiscard]] Environment* environment() const { return env_; }
186  void set_environment(Environment* env) { env_ = env; }
187  [[nodiscard]] Path environment(Environment* env) && {
188  env_ = env;
189  return std::move(*this);
190  }
191 
192  [[nodiscard]] size_t min_length() const { return min_length_; }
193  void set_min_length(size_t value) { min_length_ = value; }
194  [[nodiscard]] Path min_length(size_t value) && {
195  min_length_ = value;
196  return std::move(*this);
197  }
198 
199  [[nodiscard]] size_t max_length() const { return max_length_; }
200  void set_max_length(size_t value) { max_length_ = value; }
201  [[nodiscard]] Path max_length(size_t value) && {
202  max_length_ = value;
203  return std::move(*this);
204  }
205 
206  [[nodiscard]] const std::string& pattern() const { return pattern_; }
207  void set_pattern(const std::string& value) { pattern_ = value; }
208  [[nodiscard]] Path pattern(const std::string& value) && {
209  pattern_ = value;
210  return std::move(*this);
211  }
212 
213  public: // Overrides
214  [[nodiscard]] Json json_schema() const override;
215  bool validate(const Conf& c, std::optional<SchemaError>& err) const override;
216 
217  using Interface::to_json;
218  void to_json(Json& j) const override {
219  assert(ptr_ != nullptr);
220  j = serialize(*ptr_);
221  }
222 
223  void from_conf(const Conf& c) override {
224  assert(ptr_ != nullptr);
225  *ptr_ = deserialize(c);
226  }
227 
228  [[nodiscard]] Json serialize(const Type& x) const { return x.native(); }
229 
230  [[nodiscard]] Type deserialize(const Conf& c) const;
231 
232  void serialize_into(Json& j, const Type& x) const { j = serialize(x); }
233 
234  void deserialize_into(const Conf& c, Type& x) const { x = deserialize(c); }
235 
236  void reset_ptr() override { ptr_ = nullptr; }
237 
238  private:
239  [[nodiscard]] Type resolve_path(const Conf&, const Type&) const;
240 
241  private:
242  State req_state_{State::Any};
243  bool req_abs_{false};
244  bool resolve_{true};
245  bool normalize_{false};
246  bool interpolate_{false};
247  size_t min_length_{0};
248  size_t max_length_{std::numeric_limits<size_t>::max()};
249  std::string pattern_{};
250  Environment* env_{nullptr};
251  Type* ptr_{nullptr};
252 };
253 
254 template <typename T, typename S, std::enable_if_t<is_path_v<T>, bool> = true>
255 Path<T> make_schema(T* ptr, S&& desc) {
256  return {ptr, std::forward<S>(desc)};
257 }
258 
259 } // namespace fable::schema
Definition: server_test.cpp:72
Definition: conf.hpp:81
Definition: interface.hpp:398
virtual Json to_json() const
Definition: interface.hpp:254
Definition: path.hpp:89
Path absolute(bool value) &&
Definition: path.hpp:138
void to_json(Json &j) const override
Definition: path.hpp:218
bool resolve() const
Definition: path.hpp:150
Path state(State s) &&
Definition: path.hpp:109
void from_conf(const Conf &c) override
Definition: path.hpp:223
bool validate(const Conf &c, std::optional< SchemaError > &err) const override
Definition: path_impl.hpp:89
State state() const
Definition: path.hpp:102
Path resolve(bool value) &&
Definition: path.hpp:166
Json json_schema() const override
Definition: path_impl.hpp:66
void reset_ptr() override
Definition: path.hpp:236
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