mirror of
https://github.com/ToruNiina/toml11.git
synced 2025-12-16 03:08:52 +08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74fc70cfee | ||
|
|
91ac2debce | ||
|
|
0de89a9f19 | ||
|
|
130609bf5f | ||
|
|
ab41e7acb9 | ||
|
|
c15bc8df4a | ||
|
|
19524dbc4b | ||
|
|
c2e733a65d | ||
|
|
0c08b9e940 | ||
|
|
06197605ba | ||
|
|
5c24cfd325 |
68
README.md
68
README.md
@@ -8,7 +8,7 @@ toml11
|
||||
|
||||
c++11 header-only toml parser depending only on c++ standard library.
|
||||
|
||||
compatible to the latest version of TOML v0.5.0 after version 2.0.0.
|
||||
compatible to the latest version of [TOML v0.5.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md) after version 2.0.0.
|
||||
|
||||
Are you looking for pre-C++11 compatible toml parser? Try [Boost.toml](https://github.com/ToruNiina/Boost.toml)! It has almost the same functionality as this library and works with C++98 & Boost.
|
||||
|
||||
@@ -64,6 +64,19 @@ terminate called after throwing an instance of 'toml::syntax_error'
|
||||
| ^------ expected newline, but got '='. # error reason
|
||||
```
|
||||
|
||||
If you (mistakenly) duplicate tables and got an error, you may want to see where the other is. toml11 shows both at the same time.
|
||||
|
||||
```console
|
||||
terminate called after throwing an instance of 'toml::syntax_error'
|
||||
what(): [error] toml::insert_value: table ("table") already exists.
|
||||
--> duplicate-table.toml
|
||||
1 | [table]
|
||||
| ~~~~~~~ table already exists here
|
||||
...
|
||||
3 | [table]
|
||||
| ~~~~~~~ table defined twice
|
||||
```
|
||||
|
||||
Since the error message generation is generally a difficult task, the current status is not ideal. toml11 needs your help. If you encounter a weird error message, please let us know and contribute to improve the quality!
|
||||
|
||||
### Getting a toml value
|
||||
@@ -389,6 +402,59 @@ terminate called after throwing an instance of 'std::range_error'
|
||||
| ~~~~~~~~~ should be in [0x00..0x10FFFF]
|
||||
```
|
||||
|
||||
### Formatting your error
|
||||
|
||||
When you encounter an error after you read the toml value, you may want to
|
||||
show the error with the value.
|
||||
|
||||
toml11 provides you a function that formats user-defined error message with
|
||||
related values. With a code like the following,
|
||||
|
||||
```cpp
|
||||
const auto value = toml::find<int>(data, "num");
|
||||
if(value < 0)
|
||||
{
|
||||
std::cerr << toml::format_error("[error] value should be positive",
|
||||
data.at("num"), "positive number required")
|
||||
<< std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
you will get an error message like this.
|
||||
|
||||
```console
|
||||
[error] value should be positive
|
||||
--> example.toml
|
||||
3 | num = -42
|
||||
| ~~~ positive number required
|
||||
```
|
||||
|
||||
When you pass two values to `toml::format_error`,
|
||||
|
||||
```cpp
|
||||
const auto min = toml::find<int>(range, "min");
|
||||
const auto max = toml::find<int>(range, "max");
|
||||
if(max < min)
|
||||
{
|
||||
std::cerr << toml::format_error("[error] max should be larger than min",
|
||||
data.at("min"), "minimum number here",
|
||||
data.at("max"), "maximum number here");
|
||||
<< std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
you will get an error message like this.
|
||||
|
||||
```console
|
||||
[error] value should be positive
|
||||
--> example.toml
|
||||
3 | min = 54
|
||||
| ~~ minimum number here
|
||||
...
|
||||
4 | max = 42
|
||||
| ~~ maximum number here
|
||||
```
|
||||
|
||||
## Underlying types
|
||||
|
||||
The toml types (can be used as `toml::*` in this library) and corresponding `enum` names are listed in the table below.
|
||||
|
||||
@@ -116,6 +116,14 @@ BOOST_AUTO_TEST_CASE(test_get_exact)
|
||||
tab["key3"] = toml::value(123);
|
||||
BOOST_CHECK(tab == toml::get<toml::table>(v));
|
||||
}
|
||||
{
|
||||
toml::value v1(42);
|
||||
BOOST_CHECK(v1 == toml::get<toml::value>(v1));
|
||||
|
||||
toml::value v2(54);
|
||||
toml::get<toml::value>(v1) = v2;
|
||||
BOOST_CHECK(v2 == toml::get<toml::value>(v1));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_get_integer_type)
|
||||
|
||||
122
toml/get.hpp
122
toml/get.hpp
@@ -33,6 +33,30 @@ inline T&& get(value&& v)
|
||||
return std::move(v.cast<detail::toml_value_t<T>::value>());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// T == toml::value; identity transformation.
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
std::is_same<T, ::toml::value>::value, std::nullptr_t>::type = nullptr>
|
||||
inline T& get(value& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
std::is_same<T, ::toml::value>::value, std::nullptr_t>::type = nullptr>
|
||||
inline T const& get(const value& v)
|
||||
{
|
||||
return v;
|
||||
}
|
||||
|
||||
template<typename T, typename std::enable_if<
|
||||
std::is_same<T, ::toml::value>::value, std::nullptr_t>::type = nullptr>
|
||||
inline T&& get(value&& v)
|
||||
{
|
||||
return std::move(v);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// integer convertible from toml::Integer
|
||||
|
||||
@@ -456,52 +480,23 @@ auto get_or(toml::value&& v, const toml::key& ky, T&& opt)
|
||||
// expect
|
||||
|
||||
template<typename T>
|
||||
auto expect(const toml::value& v)
|
||||
-> result<decltype(::toml::get<T>(v)), std::string>
|
||||
result<T, std::string> expect(const toml::value& v) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(v));
|
||||
}
|
||||
catch(const type_error& te)
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
return err(te.what());
|
||||
return err(e.what());
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
auto expect(toml::value& v)
|
||||
-> result<decltype(::toml::get<T>(v)), std::string>
|
||||
result<T, std::string> expect(const toml::value& v, const toml::key& k) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(v));
|
||||
}
|
||||
catch(const type_error& te)
|
||||
{
|
||||
return err(te.what());
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
auto expect(toml::value&& v)
|
||||
-> result<decltype(::toml::get<T>(std::move(v))), std::string>
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(std::move(v)));
|
||||
}
|
||||
catch(const type_error& te)
|
||||
{
|
||||
return err(te.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto expect(const toml::value& v, const toml::key& k)
|
||||
-> result<decltype(::toml::get<T>(v, k)), std::string>
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(v, k));
|
||||
return ok(find<T>(v, k));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
@@ -509,65 +504,12 @@ auto expect(const toml::value& v, const toml::key& k)
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
auto expect(toml::value& v, const toml::key& k)
|
||||
-> result<decltype(::toml::get<T>(v, k)), std::string>
|
||||
result<T, std::string> expect(const toml::table& t, const toml::key& k,
|
||||
std::string tablename = "unknown table") noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(v, k));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
return err(e.what());
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
auto expect(toml::value&& v, const toml::key& k)
|
||||
-> result<decltype(::toml::get<T>(std::move(v), k)), std::string>
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(std::move(v), k));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
return err(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto expect(const toml::table& t, const toml::key& k, std::string tn)
|
||||
-> result<decltype(::toml::get<T>(t, k, std::move(tn))), std::string>
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(t, k, std::move(tn)));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
return err(e.what());
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
auto expect(toml::table& t, const toml::key& k, std::string tn)
|
||||
-> result<decltype(::toml::get<T>(t, k, std::move(tn))), std::string>
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(t, k, std::move(tn)));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
return err(e.what());
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
auto expect(toml::table&& t, const toml::key& k, std::string tn)
|
||||
-> result<decltype(::toml::get<T>(std::move(t), k, std::move(tn))), std::string>
|
||||
{
|
||||
try
|
||||
{
|
||||
return ok(get<T>(std::move(t), k, std::move(tn)));
|
||||
return ok(find<T>(t, k, std::move(tablename)));
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
|
||||
@@ -881,7 +881,7 @@ parse_array(location<Container>& loc)
|
||||
throw syntax_error(format_underline(
|
||||
"[error] toml::parse_array: type of elements should be the "
|
||||
"same each other.", region<Container>(loc, first, loc.iter()),
|
||||
"inhomogenous types"));
|
||||
"inhomogeneous types"));
|
||||
}
|
||||
retval.push_back(std::move(val.unwrap()));
|
||||
}
|
||||
|
||||
@@ -800,5 +800,19 @@ inline bool operator>=(const toml::value& lhs, const toml::value& rhs)
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
|
||||
inline std::string format_error(const std::string& err_msg,
|
||||
const toml::value& v, const std::string& comment)
|
||||
{
|
||||
return detail::format_underline(err_msg, detail::get_region(v), comment);
|
||||
}
|
||||
|
||||
inline std::string format_error(const std::string& err_msg,
|
||||
const toml::value& v1, const std::string& comment1,
|
||||
const toml::value& v2, const std::string& comment2)
|
||||
{
|
||||
return detail::format_underline(err_msg, detail::get_region(v1), comment1,
|
||||
detail::get_region(v2), comment2);
|
||||
}
|
||||
|
||||
}// toml
|
||||
#endif// TOML11_VALUE
|
||||
|
||||
Reference in New Issue
Block a user