Skip to content
21 changes: 17 additions & 4 deletions universal/include/userver/formats/parse/try_parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,19 @@ inline constexpr std::optional<std::string> TryParse(Value&& value, To<std::stri

template <typename Value, typename T>
inline constexpr std::optional<T> TryParse(Value&& value, To<T>) requires meta::kIsInteger<T> {
if(!((std::is_unsigned_v<T> && sizeof(T) == sizeof(std::uint64_t)) ? value.IsUInt64() : value.IsInt64())) {
return std::nullopt;
if constexpr(std::is_unsigned_v<T>) {
if(!((sizeof(T) == sizeof(std::uint64_t)) ? value.IsUInt64() : value.IsInt64())) {
return std::nullopt;
}
auto response = value.template As<std::uint64_t>();
return impl::CheckInBounds(response, std::numeric_limits<T>::min(), std::numeric_limits<T>::max()) ? std::optional{static_cast<T>(response)} : std::nullopt;
} else {
if(!value.IsInt64()) {
return std::nullopt;
}
auto response = value.template As<std::int64_t>();
return impl::CheckInBounds(response, std::numeric_limits<T>::min(), std::numeric_limits<T>::max()) ? std::optional{static_cast<T>(response)} : std::nullopt;
}
return value.template As<T>();
}
template <typename Value, typename T>
inline constexpr std::optional<std::vector<T>> TryParse(Value&& value, To<std::vector<T>>) {
Expand All @@ -80,8 +89,12 @@ inline constexpr std::optional<std::vector<T>> TryParse(Value&& value, To<std::v

template <typename T, typename Value>
constexpr inline std::optional<std::optional<T>> TryParse(Value&& value, To<std::optional<T>>) {
return TryParse(std::forward<Value>(value), To<T>{});
if (value.IsMissing() || value.IsNull()) {
return std::optional<T>{std::nullopt};
}
return TryParse(value, To<T>{});
}

template <typename Value>
constexpr inline std::optional<float> TryParse(Value&& value, To<float>) {
auto response = value.template As<double>();
Expand Down