parse/time: add consuming and non-consuming parsers

This commit is contained in:
Danny Robson 2019-03-19 17:09:03 +11:00
parent 66da52fdeb
commit 83cd6074b8
3 changed files with 33 additions and 6 deletions

View File

@ -91,7 +91,7 @@ try_consume_prefix (
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
cruft::expected<std::chrono::nanoseconds, std::errc> cruft::expected<std::chrono::nanoseconds, std::errc>
cruft::parse::duration (cruft::view<char const*> &remain) cruft::parse::duration::consume (cruft::view<char const*> &remain)
{ {
auto const count = value<std::intmax_t> (remain); auto const count = value<std::intmax_t> (remain);
if (remain.empty ()) if (remain.empty ())
@ -128,3 +128,22 @@ cruft::parse::duration (cruft::view<char const*> &remain)
return cruft::unexpected (std::errc::invalid_argument); return cruft::unexpected (std::errc::invalid_argument);
} }
//-----------------------------------------------------------------------------
cruft::expected<std::chrono::nanoseconds, std::errc>
cruft::parse::duration::from (cruft::view<char const*> const &str)
{
auto remain = str;
// Try to parse from the temporary view.
auto res = ::cruft::parse::duration::consume (remain);
if (!res)
return res;
// Ensure it was totally consumed.
if (!remain.empty ())
return cruft::unexpected (std::errc::invalid_argument);
return res;
}

View File

@ -14,14 +14,23 @@
#include <chrono> #include <chrono>
#include <system_error> #include <system_error>
namespace cruft::parse { namespace cruft::parse::duration {
/// Parse a number that represents a duration. eg, "1s", "5 minutes". /// Parse a number that represents a duration. eg, "1s", "5 minutes".
/// ///
/// The data view is updated to indicate the unused data.
///
/// When there is no suffix it is assumed the quantity is in second. /// When there is no suffix it is assumed the quantity is in second.
/// ///
/// Note: The quantities are as defined by the standard std::chrono /// Note: The quantities are as defined by the standard std::chrono
/// durations. This means that "1 month" will equal just under 30.5 days. /// durations. This means that "1 month" will equal just under 30.5 days.
/// Thus the utility is not universally useful for offsetting. /// Thus the utility is not universally useful for offsetting.
expected<std::chrono::nanoseconds, std::errc> expected<std::chrono::nanoseconds, std::errc>
duration (cruft::view<char const*> &); consume (cruft::view<char const*> &);
/// Parse a number that represent a duration (as with `consume`).
///
/// The operation will fail if the entire input is not consumed.
expected<std::chrono::nanoseconds, std::errc>
from (cruft::view<char const*> const&);
} }

View File

@ -36,9 +36,8 @@ int main ()
cruft::TAP::logger tap; cruft::TAP::logger tap;
for (auto const &[str,val,msg]: TESTS) { for (auto const &[str,val,msg]: TESTS) {
cruft::view src (str); auto res = cruft::parse::duration::from (str);
auto res = cruft::parse::duration (src); tap.expect (res && val == *res, "%! %! == %!", msg, val.count (), res->count());
tap.expect (src.empty () && res && val == *res, "%! %! == %!", msg, val.count (), res->count());
} }
return tap.status (); return tap.status ();