Skip to content

Commit c3323b9

Browse files
committed
Fixes
1 parent 30b890b commit c3323b9

File tree

1 file changed

+52
-50
lines changed

1 file changed

+52
-50
lines changed

universal/include/userver/formats/parse/try_parse.hpp

Lines changed: 52 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -15,79 +15,81 @@ USERVER_NAMESPACE_BEGIN
1515
namespace formats::parse {
1616

1717
namespace impl {
18-
19-
template <typename T, typename Value>
20-
constexpr inline bool Is(Value&& value) {
21-
if constexpr(std::is_same_v<T, bool>) {
22-
return value.IsBool();
23-
} else if constexpr(meta::kIsInteger<T>) {
24-
return (std::is_unsigned_v<T> && sizeof(T) == sizeof(std::uint64_t)) ? value.IsUInt64() : value.IsInt64();
25-
} else if constexpr(std::is_convertible_v<T, std::string>) {
26-
return value.IsString();
27-
} else if constexpr(std::is_convertible_v<T, double>) {
28-
return value.IsDouble();
29-
} else if constexpr(meta::kIsRange<T>) {
30-
return value.IsArray();
31-
} else {
32-
return value.IsObject();
33-
}
34-
}
3518
bool CheckInBounds(const auto& x, const auto& min, const auto& max) {
3619
if (x < min || x > max) {
3720
return false;
3821
};
3922
return true;
4023
};
41-
inline constexpr utils::impl::TypeList<bool, double, std::string> kBaseTypes;
4224

4325
} // namespace impl
4426

27+
template <typename Value, typename T>
28+
inline constexpr std::optional<T> TryParse(Value&& value, To<T>) {
29+
if(!value.IsObject()) {
30+
return std::nullopt;
31+
}
32+
return value.template As<T>();
33+
}
4534

46-
template <typename T, typename Value>
47-
constexpr inline std::enable_if_t<
48-
utils::impl::AnyOf(utils::impl::IsSameCarried<T>(), impl::kBaseTypes) ||
49-
meta::kIsInteger<T>, std::optional<T>>
50-
TryParse(Value&& value, userver::formats::parse::To<T>) {
51-
if(!impl::Is<T>(value)) {
35+
template <typename Value>
36+
inline constexpr std::optional<bool> TryParse(Value&& value, To<bool>) {
37+
if(!value.IsBool()) {
38+
return std::nullopt;
39+
}
40+
return value.template As<bool>();
41+
}
42+
template <typename Value>
43+
inline constexpr std::optional<double> TryParse(Value&& value, To<double>) {
44+
if(!value.IsDouble()) {
45+
return std::nullopt;
46+
}
47+
return value.template As<double>();
48+
}
49+
template <typename Value>
50+
inline constexpr std::optional<std::string> TryParse(Value&& value, To<std::string>) {
51+
if(!value.IsString()) {
52+
return std::nullopt;
53+
}
54+
return value.template As<std::string>();
55+
}
56+
57+
template <typename Value, typename T>
58+
inline constexpr std::optional<T> TryParse(Value&& value, To<T>) requires meta::kIsInteger<T> {
59+
if(!((std::is_unsigned_v<T> && sizeof(T) == sizeof(std::uint64_t)) ? value.IsUInt64() : value.IsInt64())) {
5260
return std::nullopt;
5361
}
5462
return value.template As<T>();
5563
}
64+
template <typename Value, typename T>
65+
inline constexpr std::optional<std::vector<T>> TryParse(Value&& value, To<std::vector<T>>) {
66+
if(!value.IsArray()) {
67+
return std::nullopt;
68+
}
69+
std::vector<T> response;
70+
response.reserve(value.GetSize());
71+
for(const auto& item : value) {
72+
auto insert = TryParse(item, To<T>{});
73+
if(!insert) {
74+
return std::nullopt;
75+
}
76+
response.push_back(std::move(*insert));
77+
}
78+
return response;
79+
}
5680

5781
template <typename T, typename Value>
58-
constexpr inline std::optional<std::optional<T>> TryParse(Value&& value, userver::formats::parse::To<std::optional<T>>) {
59-
return TryParse(std::forward<Value>(value), userver::formats::parse::To<T>{});
82+
constexpr inline std::optional<std::optional<T>> TryParse(Value&& value, To<std::optional<T>>) {
83+
return TryParse(std::forward<Value>(value), To<T>{});
6084
}
6185
template <typename Value>
62-
constexpr inline std::optional<float> TryParse(Value&& value, userver::formats::parse::To<float>) {
86+
constexpr inline std::optional<float> TryParse(Value&& value, To<float>) {
6387
auto response = value.template As<double>();
6488
if(impl::CheckInBounds(response, std::numeric_limits<float>::lowest(),
6589
std::numeric_limits<float>::max())) {
6690
return static_cast<float>(response);
67-
};
91+
}
6892
return std::nullopt;
69-
};
70-
71-
template <typename T, typename Value>
72-
constexpr inline std::enable_if_t<meta::kIsRange<T> && !meta::kIsMap<T> &&
73-
!std::is_same_v<T, boost::uuids::uuid> &&
74-
!utils::impl::AnyOf(utils::impl::IsConvertableCarried<T>(), impl::kBaseTypes) &&
75-
!std::is_convertible_v<
76-
T&, utils::impl::strong_typedef::StrongTypedefTag&>,
77-
std::optional<T>>
78-
TryParse(Value&& from, To<T>) {
79-
T response;
80-
auto inserter = std::inserter(response, response.end());
81-
using ValueType = meta::RangeValueType<T>;
82-
for(const auto& item : from) {
83-
auto insert = TryParse(item, userver::formats::parse::To<ValueType>{});
84-
if(!insert) {
85-
return std::nullopt;
86-
};
87-
*inserter = *insert;
88-
++inserter;
89-
};
90-
return response;
9193
}
9294

9395

0 commit comments

Comments
 (0)