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"
23#include "toml_file_exporter.h"
24
25
26namespace designlab
27{
28
32template <typename T>
33concept HasFromToml = std::is_default_constructible_v<T> && impl::has_from_toml<T>::value;
34
35
40template <HasFromToml T>
42{
43public:
44 TomlFileImporter() : validator_(std::make_unique<TomlDataValidatorAlwaysTrue<T>>()) {}
45
46 explicit TomlFileImporter(std::unique_ptr<ITomlDataValidator<T>>&& validator) : validator_(std::move(validator)) {}
47
48
52 std::optional<T> Import(const std::string& file_path) const
53 {
54 if (do_output_message_)
55 {
57 CmdIOUtil::SystemOutput("Loads a file. file_path : " + file_path);
58 }
59
60 if (!FileIsExist(file_path)) { return std::nullopt; }
61
62 toml::value toml_value;
63
64 if (!ParseTomlFile(file_path, &toml_value)) { return std::nullopt; }
65
66 T data;
67
68 if (!SerializeTomlData(&toml_value, &data)) { return std::nullopt; }
69
70 if (!ValidateData(data)) { return std::nullopt; }
71
72 if (do_output_message_)
73 {
74 CmdIOUtil::SystemOutput("Loading completed successfully.");
76 }
77
78 return data;
79 }
80
87 T ImportOrUseDefault(const std::string& file_path) const
88 {
89 const auto data = Import(file_path);
90
91 if (data.has_value()) { return data.value(); }
92
93 if (CmdIOUtil::InputYesNo("Do you want to output a default file?"))
94 {
95 TomlFileExporter<T> exporter;
96 exporter.Export(file_path, T());
97 }
98
99 CmdIOUtil::SystemOutput("Use default data.");
101
102 return T();
103 }
104
105private:
106 bool FileIsExist(const std::string& file_path) const
107 {
108 if (do_output_message_)
109 {
110 CmdIOUtil::InfoOutput("Check if the file exists. ");
111 }
112
113 if (!std::filesystem::exists(file_path))
114 {
115 if (do_output_message_)
116 {
117 CmdIOUtil::ErrorOutput("The file does not exist.");
119 }
120
121 return false;
122 }
123
124 if (do_output_message_)
125 {
126 CmdIOUtil::InfoOutput("The file found.");
127 }
128
129 return true;
130 }
131
132 bool ParseTomlFile(const std::string& file_path, toml::value* toml_value) const
133 {
134 if (do_output_message_)
135 {
136 CmdIOUtil::InfoOutput("Start parsing.");
137 }
138
139 try
140 {
141 // バイナリモードで読み込む.
142 std::ifstream ifs(file_path, std::ios::binary);
143
144 *toml_value = toml::parse(ifs, file_path);
145 }
146 catch (toml::syntax_error err)
147 {
148 if (do_output_message_)
149 {
150 CmdIOUtil::ErrorOutput("File parsing failed.");
152 CmdIOUtil::ErrorOutput("< Rows that failed to parse >");
153 CmdIOUtil::ErrorOutput(err.what());
155 }
156
157 return false;
158 }
159
160 if (do_output_message_)
161 {
162 CmdIOUtil::InfoOutput("File parsing succeeded.");
163 }
164
165 return true;
166 }
167
168 bool SerializeTomlData(toml::value* toml_value, T* data) const
169 {
170 if (do_output_message_)
171 {
172 CmdIOUtil::InfoOutput("Serialize data.");
173 }
174
175 try
176 {
177 *data = toml::from<T>::from_toml(*toml_value);
178 }
179 catch (...)
180 {
181 if (do_output_message_)
182 {
183 CmdIOUtil::ErrorOutput("Data serialization failed.");
185 }
186
187 return false;
188 }
189
190 if (do_output_message_)
191 {
192 CmdIOUtil::InfoOutput("Data serialization succeeded.");
193 }
194
195 return true;
196 }
197
198 bool ValidateData(const T& data) const
199 {
200 if (do_output_message_)
201 {
202 CmdIOUtil::InfoOutput("Start data validation.");
203 }
204
205 const auto [is_valid, error_message] = validator_->Validate(data);
206
207 if (!is_valid)
208 {
209 if (do_output_message_)
210 {
211 CmdIOUtil::ErrorOutput("Data validation failed.");
213 CmdIOUtil::ErrorOutput("<Reasons for Failure to Verify>");
214 CmdIOUtil::ErrorOutput(error_message);
216 }
217
218 return false;
219 }
220
221 if (do_output_message_)
222 {
223 CmdIOUtil::InfoOutput("Data validation succeeded.");
224 }
225
226 return true;
227 }
228
229 bool do_output_message_{ true };
230
231 const std::unique_ptr<ITomlDataValidator<T>> validator_;
232};
233
234} // namespace designlab
235
236
237#endif // DESIGNLAB_TOML_FILE_IMPORTER_H_
static void SystemOutput(const std::string &str)
コマンドラインに文字を出力する関数.System用の出力.
Definition cmdio_util.h:105
static void ErrorOutput(const std::string &str)
コマンドラインに文字を出力する関数.Error用の出力.
Definition cmdio_util.h:98
static void OutputNewLine(int num, OutputDetail detail)
コマンドラインで改行をする関数.
static bool InputYesNo(const std::string &str="Are you sure?")
yesかnoを入力させる関数.返り値で yes なら true,noなら falseを返す. 出力される文字列は,必ず OutputDetail::kSystem で出力される.
static void InfoOutput(const std::string &str)
コマンドラインに文字を出力する関数.Info用の出力.
Definition cmdio_util.h:84
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()が定義されているかどうかを判定する. また,デフォルトコンストラクタが実装されているかどうかも判...
@ kSystem
システムメッセージ,常に出力する.
@ kError
エラーメッセージ.
Definition com_type.h:24