diff --git a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp index cc5c266064..d971ca4225 100644 --- a/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp +++ b/3party/opening_hours/opening_hours_tests/osm_time_range_tests.cpp @@ -574,7 +574,30 @@ BOOST_AUTO_TEST_CASE(OpeningHoursYearRanges_TestParseUnparse) auto const parsedUnparsed = ParseAndUnparse(rule); BOOST_CHECK_EQUAL(parsedUnparsed, rule); } +} +BOOST_AUTO_TEST_CASE(OpeningHoursWeekRanges_TestParseUnparse) +{ + { + auto const rule = "week 15"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } + { + auto const rule = "week 19-31"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } + { + auto const rule = "week 18-36/3"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } + { + auto const rule = "week 18-36/3,11"; + auto const parsedUnparsed = ParseAndUnparse(rule); + BOOST_CHECK_EQUAL(parsedUnparsed, rule); + } } // BOOST_AUTO_TEST_CASE(OpeningHours_TimeHit) diff --git a/3party/opening_hours/osm_parsers.hpp b/3party/opening_hours/osm_parsers.hpp index b8d0e0cd58..d3b6db127d 100644 --- a/3party/opening_hours/osm_parsers.hpp +++ b/3party/opening_hours/osm_parsers.hpp @@ -122,28 +122,35 @@ class year_selector : public qi::grammar -// class week_selector : public qi::grammar -// { -// protected: -// qi::rule week; -// qi::rule year_range; -// qi::rule main; -// public: -// week_selector() : week_selector::base_type(main) -// { -// using qi::uint_; -// using qi::lit; -// using charset::char_; +template +class week_selector : public qi::grammar +{ + protected: + qi::rule week; + qi::rule main; -// week %= (weeknum >> dash >> weeknum >> '/' >> uint_) -// | (weeknum >> dash >> weeknum) -// | weeknum -// ; + public: + week_selector() : week_selector::base_type(main) + { + using qi::uint_; + using qi::lit; + using qi::_1; + using qi::_2; + using qi::_3; + using qi::_val; -// main %= charset::no_case[lit("week")] >> week % ','; -// } -// }; + week = (weeknum >> dash >> weeknum >> '/' >> uint_) + [bind(&osmoh::WeekRange::SetStart, _val, _1), + bind(&osmoh::WeekRange::SetEnd, _val, _2), + bind(&osmoh::WeekRange::SetPeriod, _val, _3)] + | (weeknum >> dash >> weeknum) [bind(&osmoh::WeekRange::SetStart, _val, _1), + bind(&osmoh::WeekRange::SetEnd, _val, _2)] + | weeknum [bind(&osmoh::WeekRange::SetStart, _val, _1)] + ; + + main %= charset::no_case[lit("week")] >> (week % ','); + } +}; template class month_selector : public qi::grammar diff --git a/3party/opening_hours/osm_time_range.cpp b/3party/opening_hours/osm_time_range.cpp index e7ac35413e..ca6ec3d474 100644 --- a/3party/opening_hours/osm_time_range.cpp +++ b/3party/opening_hours/osm_time_range.cpp @@ -987,6 +987,77 @@ std::ostream & operator<<(std::ostream & ost, TYearRanges const ranges) return ost; } + +bool WeekRange::IsEmpty() const +{ + return !HasStart() && !HasEnd(); +} + +bool WeekRange::HasStart() const +{ + return GetStart() != 0; +} + +bool WeekRange::HasEnd() const +{ + return GetEnd() != 0; +} + +bool WeekRange::HasPeriod() const +{ + return GetPeriod() != 0; +} + +WeekRange::TWeek WeekRange::GetStart() const +{ + return m_start; +} + +WeekRange::TWeek WeekRange::GetEnd() const +{ + return m_end; +} + +uint32_t WeekRange::GetPeriod() const +{ + return m_period; +} + +void WeekRange::SetStart(TWeek const start) +{ + m_start = start; +} + +void WeekRange::SetEnd(TWeek const end) +{ + m_end = end; +} + +void WeekRange::SetPeriod(uint32_t const period) +{ + m_period = period; +} + +std::ostream & operator<<(std::ostream & ost, WeekRange const range) +{ + PrintPaddedNumber(ost, range.GetStart(), 2); + if (range.HasEnd()) + { + ost << '-'; + PrintPaddedNumber(ost, range.GetEnd(), 2); + if (range.HasPeriod()) + ost << '/' << range.GetPeriod(); + } + return ost; +} + +std::ostream & operator<<(std::ostream & ost, TWeekRanges const ranges) +{ + ost << "week "; + PrintVector(ost, ranges); + return ost; +} + // std::ostream & operator << (std::ostream & s, State const & w) // { // static char const * st[] = {"unknown", "closed", "open"}; diff --git a/3party/opening_hours/osm_time_range.hpp b/3party/opening_hours/osm_time_range.hpp index 5338d0f74b..843c2da647 100644 --- a/3party/opening_hours/osm_time_range.hpp +++ b/3party/opening_hours/osm_time_range.hpp @@ -448,6 +448,36 @@ using TYearRanges = std::vector; std::ostream & operator<<(std::ostream & ost, YearRange const range); std::ostream & operator<<(std::ostream & ost, TYearRanges const ranges); + +class WeekRange +{ + public: + using TWeek = uint8_t; + + public: + bool IsEmpty() const; + bool HasStart() const; + bool HasEnd() const; + bool HasPeriod() const; + + TWeek GetStart() const; + TWeek GetEnd() const; + uint32_t GetPeriod() const; + + void SetStart(TWeek const start); + void SetEnd(TWeek const end); + void SetPeriod(uint32_t const period); + + private: + TWeek m_start{}; + TWeek m_end{}; + uint32_t m_period{0}; +}; + +using TWeekRanges = std::vector; + +std::ostream & operator<<(std::ostream & ost, WeekRange const range); +std::ostream & operator<<(std::ostream & ost, TWeekRanges const ranges); } // namespace osmoh diff --git a/3party/opening_hours/parse.cpp b/3party/opening_hours/parse.cpp index 9f14c6e167..06503608e8 100644 --- a/3party/opening_hours/parse.cpp +++ b/3party/opening_hours/parse.cpp @@ -26,6 +26,12 @@ template struct context_parser using type = osmoh::parsing::year_selector; }; +template struct context_parser +{ + using type = osmoh::parsing::week_selector; +}; + + template using context_parser_t = typename context_parser::type; @@ -56,6 +62,7 @@ bool ParseImp(std::string const & str, Context & context) } } // namespace + namespace osmoh { bool Parse(std::string const & str, TTimespans & s) @@ -77,4 +84,9 @@ bool Parse(std::string const & str, TYearRanges & y) { return ParseImp(str, y); } + +bool Parse(std::string const & str, TWeekRanges & w) +{ + return ParseImp(str, w); +} } // namespace osmoh diff --git a/3party/opening_hours/parse.hpp b/3party/opening_hours/parse.hpp index 913511553f..f1574cad77 100644 --- a/3party/opening_hours/parse.hpp +++ b/3party/opening_hours/parse.hpp @@ -9,4 +9,5 @@ bool Parse(std::string const &, TTimespans &); bool Parse(std::string const &, Weekdays &); bool Parse(std::string const &, TMonthdayRanges &); bool Parse(std::string const &, TYearRanges &); +bool Parse(std::string const &, TWeekRanges &); } // namespace osmoh