diff options
author | Idan Horowitz <idan.horowitz@gmail.com> | 2021-07-11 21:00:04 +0300 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-07-12 19:05:17 +0100 |
commit | 141c46feda1c91f3b50948749463ecf7c380aa1a (patch) | |
tree | e2d379aa146d9fef5c6b2432e99923f7cc040b15 | |
parent | 39a9cf4bb49751b49c63fa8b1c65555afc73d0e7 (diff) | |
download | serenity-141c46feda1c91f3b50948749463ecf7c380aa1a.zip |
AK: Add a DateTimeLexer
This is an AK::GenericLexer that exposes helper methods for parsing
date and time related literals (years, months, days, hours, minutes,
seconds, fractional seconds & more)
-rw-r--r-- | AK/DateTimeLexer.h | 146 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp | 21 | ||||
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h | 17 |
3 files changed, 146 insertions, 38 deletions
diff --git a/AK/DateTimeLexer.h b/AK/DateTimeLexer.h new file mode 100644 index 0000000000..51de0c4266 --- /dev/null +++ b/AK/DateTimeLexer.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/CharacterTypes.h> +#include <AK/GenericLexer.h> +#include <AK/Optional.h> + +namespace AK { + +class DateTimeLexer : public GenericLexer { +public: + constexpr explicit DateTimeLexer(const StringView& input) + : GenericLexer(input) + { + } + + Optional<StringView> consume_year() + { + if (tell_remaining() < 4) + return {}; + + for (auto i = 0; i < 4; ++i) { + if (!is_ascii_digit(peek(i))) + return {}; + } + return consume(4); + } + + Optional<StringView> consume_month() + { + if (tell_remaining() < 2) + return {}; + + auto tens = peek(); + if (tens != '0' && tens != '1') + return {}; + + auto ones = peek(1); + if (!is_ascii_digit(ones)) + return {}; + + if (tens == '0') { // 01, 02, 03, 04, 05, 06, 07, 08, 09 + if (ones == '0') + return {}; + } else if (ones > '2') { // 10, 11, 12 + return {}; + } + + return consume(2); + } + + Optional<StringView> consume_day() + { + if (tell_remaining() < 2) + return {}; + + auto tens = peek(); + if (tens < '0' || tens > '3') + return {}; + + auto ones = peek(1); + if (!is_ascii_digit(ones)) + return {}; + + if (tens == '0') { // 01, 02, 03, 04, 05, 06, 07, 08, 09 + if (ones == '0') + return {}; + } else if (tens == '3') { // 30, 31 + if (ones != '0' && ones != '1') + return {}; + } else if (!is_ascii_digit(ones)) { // 10 - 29 + return {}; + } + + return consume(2); + } + + Optional<StringView> consume_sign() + { + if (!tell_remaining()) + return {}; + + if (next_is("\xE2\x88\x92"sv)) + return consume(3); + else if (next_is('-') || next_is('+')) + return consume(1); + else + return {}; + }; + + Optional<StringView> consume_hours() + { + if (tell_remaining() < 2) + return {}; + + char tens = peek(); + if (tens != '0' && tens != '1' && tens != '2') + return {}; + + char ones = peek(1); + if (!is_ascii_digit(ones) || (tens == '2' && ones > '3')) + return {}; + + return consume(2); + } + + Optional<StringView> consume_minutes_or_seconds() + { + if (tell_remaining() < 2) + return {}; + + char tens = peek(); + if (tens < '0' || tens > '5') + return {}; + + if (!is_ascii_digit(peek(1))) + return {}; + + return consume(2); + } + + Optional<StringView> consume_fractional_seconds() + { + if (!tell_remaining()) + return {}; + + auto length = min(tell_remaining(), 9); + for (size_t i = 0; i < length; ++i) { + if (is_ascii_digit(peek(i))) + continue; + length = i; + break; + } + + return consume(length); + } +}; + +} + +using AK::DateTimeLexer; diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp deleted file mode 100644 index 737228becd..0000000000 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2021, Linus Groh <linusg@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include <AK/String.h> -#include <LibJS/Runtime/Temporal/ISO8601.h> - -namespace JS::Temporal { - -// 13.33 ISO 8601 grammar, https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar - -// TimeZoneNumericUTCOffset, https://tc39.es/proposal-temporal/#prod-TimeZoneNumericUTCOffset -bool is_valid_time_zone_numeric_utc_offset(String const&) -{ - // TODO: Implement me :^) - return false; -} - -} diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h b/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h deleted file mode 100644 index a800773d17..0000000000 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ISO8601.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2021, Linus Groh <linusg@serenityos.org> - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include <LibJS/Forward.h> - -namespace JS::Temporal { - -// 13.33 ISO 8601 grammar, https://tc39.es/proposal-temporal/#sec-temporal-iso8601grammar - -bool is_valid_time_zone_numeric_utc_offset(String const&); - -} |