ISO8601.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/GenericLexer.h>
  8. #include <AK/Optional.h>
  9. #include <AK/StringView.h>
  10. #include <AK/Vector.h>
  11. namespace JS::Temporal {
  12. struct ParseResult {
  13. Optional<StringView> sign;
  14. Optional<StringView> date_year;
  15. Optional<StringView> date_month;
  16. Optional<StringView> date_day;
  17. Optional<StringView> time_hour;
  18. Optional<StringView> time_minute;
  19. Optional<StringView> time_second;
  20. Optional<StringView> time_fractional_part;
  21. Optional<StringView> calendar_name;
  22. };
  23. enum class Production {
  24. TemporalDateString,
  25. TemporalDateTimeString,
  26. };
  27. Optional<ParseResult> parse_iso8601(Production, StringView);
  28. namespace Detail {
  29. class ISO8601Parser {
  30. public:
  31. explicit ISO8601Parser(StringView input)
  32. : m_input(input)
  33. , m_state({
  34. .lexer = GenericLexer { input },
  35. .parse_result = {},
  36. })
  37. {
  38. }
  39. [[nodiscard]] GenericLexer const& lexer() const { return m_state.lexer; }
  40. [[nodiscard]] ParseResult const& parse_result() const { return m_state.parse_result; }
  41. [[nodiscard]] bool parse_decimal_digit();
  42. [[nodiscard]] bool parse_non_zero_digit();
  43. [[nodiscard]] bool parse_ascii_sign();
  44. [[nodiscard]] bool parse_sign();
  45. [[nodiscard]] bool parse_hour();
  46. [[nodiscard]] bool parse_minute_second();
  47. [[nodiscard]] bool parse_decimal_separator();
  48. [[nodiscard]] bool parse_date_time_separator();
  49. [[nodiscard]] bool parse_date_year();
  50. [[nodiscard]] bool parse_date_month();
  51. [[nodiscard]] bool parse_date_day();
  52. [[nodiscard]] bool parse_date();
  53. [[nodiscard]] bool parse_time_hour();
  54. [[nodiscard]] bool parse_time_minute();
  55. [[nodiscard]] bool parse_time_second();
  56. [[nodiscard]] bool parse_fractional_part();
  57. [[nodiscard]] bool parse_time_fractional_part();
  58. [[nodiscard]] bool parse_fraction();
  59. [[nodiscard]] bool parse_time_fraction();
  60. [[nodiscard]] bool parse_time_zone_offset_required();
  61. [[nodiscard]] bool parse_time_zone_name_required();
  62. [[nodiscard]] bool parse_time_zone();
  63. [[nodiscard]] bool parse_calendar_name();
  64. [[nodiscard]] bool parse_calendar();
  65. [[nodiscard]] bool parse_time_spec();
  66. [[nodiscard]] bool parse_time_spec_separator();
  67. [[nodiscard]] bool parse_date_time();
  68. [[nodiscard]] bool parse_calendar_date_time();
  69. [[nodiscard]] bool parse_temporal_date_string();
  70. private:
  71. struct State {
  72. GenericLexer lexer;
  73. ParseResult parse_result;
  74. };
  75. struct StateTransaction {
  76. explicit StateTransaction(ISO8601Parser& parser)
  77. : m_parser(parser)
  78. , m_saved_state(parser.m_state)
  79. , m_start_index(parser.m_state.lexer.tell())
  80. {
  81. }
  82. ~StateTransaction()
  83. {
  84. if (!m_commit)
  85. m_parser.m_state = move(m_saved_state);
  86. }
  87. void commit() { m_commit = true; }
  88. StringView parsed_string_view() const
  89. {
  90. return m_parser.m_input.substring_view(m_start_index, m_parser.m_state.lexer.tell() - m_start_index);
  91. }
  92. private:
  93. ISO8601Parser& m_parser;
  94. State m_saved_state;
  95. size_t m_start_index { 0 };
  96. bool m_commit { false };
  97. };
  98. StringView m_input;
  99. State m_state;
  100. };
  101. }
  102. }