userver: /data/code/userver/libraries/proto-structs/src/proto-structs/date.cpp Source File
Loading...
Searching...
No Matches
date.cpp
1#include <userver/proto-structs/date.hpp>
2
3#include <fmt/format.h>
4
5#include <userver/proto-structs/exceptions.hpp>
6#include <userver/utils/impl/internal_tag.hpp>
7
8USERVER_NAMESPACE_BEGIN
9
10namespace proto_structs {
11
12Date::Date(utils::impl::InternalTag, std::int32_t year, std::int32_t month, std::int32_t day) {
13 if (!IsValid(utils::impl::InternalTag{}, year, month, day)) {
14 ThrowError(year, month, day, "invalid or out of range");
15 }
16
17 if (year != 0) {
18 year_.emplace(year);
19 }
20
21 if (month != 0) {
22 month_.emplace(static_cast<unsigned>(month));
23 }
24
25 if (day != 0) {
26 day_.emplace(static_cast<unsigned>(day));
27 }
28}
29
30bool Date::IsValid(
31 utils::impl::InternalTag,
32 std::int32_t year_num,
33 std::int32_t month_num,
34 std::int32_t day_num
35) noexcept {
36 std::optional<std::chrono::year> year;
37 std::optional<std::chrono::month> month;
38 std::optional<std::chrono::day> day;
39
40 if (year_num != 0) {
41 year.emplace(year_num);
42 }
43
44 if (month_num != 0) {
45 if (month_num > 0 && month_num <= 12) {
46 month.emplace(static_cast<unsigned>(month_num));
47 } else {
48 return false;
49 }
50 }
51
52 if (day_num != 0) {
53 if (day_num > 0 && day_num <= 31) {
54 day.emplace(static_cast<unsigned>(day_num));
55 } else {
56 return false;
57 }
58 }
59
60 return IsValid(year, month, day);
61}
62
63void Date::ThrowError(std::int32_t year, std::int32_t month, std::int32_t day, const char* reason) {
64 throw ValueError(fmt::format("Date '{}y/{}m/{}d' error: {}", year, month, day, reason));
65}
66} // namespace proto_structs
67
68USERVER_NAMESPACE_END