/* * Copyright (c) 2021, Idan Horowitz * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace AK { class DateTimeLexer : public GenericLexer { public: constexpr explicit DateTimeLexer(StringView input) : GenericLexer(input) { } Optional 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 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 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 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 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 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 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); } }; } #if USING_AK_GLOBALLY using AK::DateTimeLexer; #endif