GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
toml_file_importer.h
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#ifndef DESIGNLAB_TOML_FILE_IMPORTER_H_
9#define DESIGNLAB_TOML_FILE_IMPORTER_H_
10
11#include <concepts>
12#include <filesystem>
13#include <fstream>
14#include <memory>
15#include <optional>
16#include <string>
17#include <utility>
18
19#include "cmdio_util.h"
22#include "my_expected.h"
24#include "toml_file_exporter.h"
25
26namespace designlab {
27
31template <typename T>
32concept HasFromToml =
33 std::is_default_constructible_v<T> && impl::has_from_toml<T>::value;
34
39template <HasFromToml T>
40class TomlFileImporter final {
41 public:
43 : validator_(std::make_unique<TomlDataValidatorAlwaysTrue<T>>()) {}
44
45 explicit TomlFileImporter(std::unique_ptr<ITomlDataValidator<T>>&& validator)
46 : validator_(std::move(validator)) {}
47
51 std::optional<T> Import(const std::string& file_path) const {
52 if (do_output_message_) {
54 cmdio::SystemOutput("Loads a file. file_path : " + file_path);
55 }
56
57 if (!FileIsExist(file_path)) {
58 return std::nullopt;
59 }
60
61 toml::value toml_value;
62
63 if (!ParseTomlFile(file_path, &toml_value)) {
64 return std::nullopt;
65 }
66
67 T data;
68
69 if (!SerializeTomlData(&toml_value, &data)) {
70 return std::nullopt;
71 }
72
73 if (!ValidateData(data)) {
74 return std::nullopt;
75 }
76
77 if (do_output_message_) {
78 cmdio::SystemOutput("Loading completed successfully.");
80 }
81
82 return data;
83 }
84
91 T ImportOrUseDefault(const std::string& file_path) const {
92 const auto data = Import(file_path);
93
94 if (data.has_value()) {
95 return data.value();
96 }
97
98 if (cmdio::InputYesNo("Do you want to output a default file?")) {
99 TomlFileExporter<T> exporter;
100 exporter.Export(file_path, T());
101 }
102
103 cmdio::SystemOutput("Use default data.");
105
106 return T();
107 }
108
109 private:
110 bool FileIsExist(const std::string& file_path) const {
111 if (do_output_message_) {
112 cmdio::InfoOutput("Check if the file exists. ");
113 }
114
115 if (!std::filesystem::exists(file_path)) {
116 if (do_output_message_) {
117 cmdio::ErrorOutput("The file does not exist.");
119 }
120
121 return false;
122 }
123
124 if (do_output_message_) {
125 cmdio::InfoOutput("The file found.");
126 }
127
128 return true;
129 }
130
131 bool ParseTomlFile(const std::string& file_path,
132 toml::value* toml_value) const {
133 if (do_output_message_) {
134 cmdio::InfoOutput("Start parsing.");
135 }
136
137 try {
138 // バイナリモードで読み込む.
139 std::ifstream ifs(file_path, std::ios::binary);
140
141 *toml_value = toml::parse(ifs, file_path);
142 } catch (toml::syntax_error err) {
143 if (do_output_message_) {
144 cmdio::ErrorOutput("File parsing failed.");
146 cmdio::ErrorOutput("< Rows that failed to parse >");
147 cmdio::ErrorOutput(err.what());
149 }
150
151 return false;
152 }
153
154 if (do_output_message_) {
155 cmdio::InfoOutput("File parsing succeeded.");
156 }
157
158 return true;
159 }
160
161 bool SerializeTomlData(toml::value* toml_value, T* data) const {
162 if (do_output_message_) {
163 cmdio::InfoOutput("Serialize data.");
164 }
165
166 try {
167 *data = toml::from<T>::from_toml(*toml_value);
168 } catch (...) {
169 if (do_output_message_) {
170 cmdio::ErrorOutput("Data serialization failed.");
172 }
173
174 return false;
175 }
176
177 if (do_output_message_) {
178 cmdio::InfoOutput("Data serialization succeeded.");
179 }
180
181 return true;
182 }
183
184 bool ValidateData(const T& data) const {
185 if (do_output_message_) {
186 cmdio::InfoOutput("Start data validation.");
187 }
188
189 const auto [is_valid, error_message] = validator_->Validate(data);
190
191 if (!is_valid) {
192 if (do_output_message_) {
193 cmdio::ErrorOutput("Data validation failed.");
195 cmdio::ErrorOutput("<Reasons for Failure to Verify>");
196 cmdio::ErrorOutput(error_message);
198 }
199
200 return false;
201 }
202
203 if (do_output_message_) {
204 cmdio::InfoOutput("Data validation succeeded.");
205 }
206
207 return true;
208 }
209
210 bool do_output_message_{true};
211
212 const std::unique_ptr<ITomlDataValidator<T>> validator_;
213};
214
215} // namespace designlab
216
217#endif // DESIGNLAB_TOML_FILE_IMPORTER_H_
TOMLファイルのデータの検証を行う処理のインターフェース.
常に trueを返す ITomlDataValidator の実装クラス.
TOMLファイルを出力するテンプレートクラス.
void Export(const std::string &file_path, const T &data)
TOMLファイルを出力する.
tomlファイルを読み込んで構造体に変換するテンプレートクラス.
std::optional< T > Import(const std::string &file_path) const
指定したファイルパスのファイルを読み込み,構造体に変換する.
T ImportOrUseDefault(const std::string &file_path) const
指定したファイルパスのファイルを読み込み,構造体に変換する. 読込に失敗した場合は,デフォルトの構造体を返す. また,読込に失敗した場合には, デフォルトの構造体をファイルに出力するかどうかをユーザに問...
TomlFileImporter(std::unique_ptr< ITomlDataValidator< T > > &&validator)
FromTomlを持つか判定するコンセプト. toml::from<T>::from_toml()が定義されているかどうかを判定する. また,デフォルトコンストラクタが実装されているかどうかも判...
void ErrorOutput(const std::string &str)
コマンドラインに文字を出力する関数. Error 用の出力.
Definition cmdio_util.h:69
void SystemOutput(const std::string &str)
コマンドラインに文字を出力する関数. System 用の出力.
Definition cmdio_util.h:75
void InfoOutput(const std::string &str)
コマンドラインに文字を出力する関数. Info 用の出力.
Definition cmdio_util.h:57
void OutputNewLine(int num, OutputDetail detail)
コマンドラインで改行をする関数.
bool InputYesNo(const std::string &str="Are you sure?")
yesかnoを入力させる関数.返り値で yes なら true, no なら false を返す. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
@ kSystem
システムメッセージ,常に出力する.
@ kError
エラーメッセージ.
Definition com_type.h:21