#include "foundation/parse.h"

#include <charconv>

namespace pp::foundation {

Result<std::uint32_t> parse_u32(std::string_view text) noexcept
{
    if (text.empty()) {
        return Result<std::uint32_t>::failure(
            Status::invalid_argument("value must not be empty"));
    }

    if (text.front() == '-' || text.front() == '+') {
        return Result<std::uint32_t>::failure(
            Status::invalid_argument("value must be an unsigned integer without a sign"));
    }

    std::uint32_t value = 0;
    const auto* begin = text.data();
    const auto* end = text.data() + text.size();
    const auto [ptr, ec] = std::from_chars(begin, end, value);

    if (ec == std::errc::result_out_of_range) {
        return Result<std::uint32_t>::failure(
            Status::out_of_range("value is outside the uint32 range"));
    }

    if (ec != std::errc {} || ptr != end) {
        return Result<std::uint32_t>::failure(
            Status::invalid_argument("value must contain only decimal digits"));
    }

    return Result<std::uint32_t>::success(value);
}

}
