comparison src/core/date.cc @ 202:71832ffe425a

animia: re-add kvm fd source this is all being merged from my wildly out-of-date laptop. SORRY! in other news, I edited the CI file to install the wayland client as well, so the linux CI build might finally get wayland stuff.
author Paper <paper@paper.us.eu.org>
date Tue, 02 Jan 2024 06:05:06 -0500
parents bc1ae1810855
children 862d0d8619f6
comparison
equal deleted inserted replaced
201:8f6f8dd2eb23 202:71832ffe425a
1 #include "core/date.h" 1 #include "core/date.h"
2 #include "core/json.h" 2 #include "core/json.h"
3
3 #include <QDate> 4 #include <QDate>
4 #include <QDebug> 5 #include <QDebug>
6
5 #include <algorithm> 7 #include <algorithm>
6 #include <cstdint>
7 #include <tuple>
8 8
9 /* An implementation of AniList's "fuzzy date" */ 9 /* An implementation of AniList's "fuzzy date" */
10
11 #define CLAMP(x, low, high) (std::max(low, std::min(high, x)))
12 10
13 Date::Date() { 11 Date::Date() {
14 } 12 }
15 13
16 Date::Date(unsigned int y) { 14 Date::Date(unsigned int y) {
27 SetYear(date.year()); 25 SetYear(date.year());
28 SetMonth(date.month()); 26 SetMonth(date.month());
29 SetDay(date.day()); 27 SetDay(date.day());
30 } 28 }
31 29
30 Date::Date(const nlohmann::json& json) {
31 /* NOTE: this constructor is made for use with
32 AniList FuzzyDate-style JSON. In the future, some other
33 methods may be parsed and whatnot if necessary. */
34
35 if (json.contains("/year"_json_pointer) && json.at("/year"_json_pointer).is_number())
36 SetYear(json.at("/year"_json_pointer).get<unsigned int>());
37 if (json.contains("/month"_json_pointer) && json.at("/month"_json_pointer).is_number())
38 SetMonth(json.at("/month"_json_pointer).get<unsigned int>());
39 if (json.contains("/day"_json_pointer) && json.at("/day"_json_pointer).is_number())
40 SetDay(json.at("/day"_json_pointer).get<unsigned int>());
41 }
42
32 void Date::VoidYear() { 43 void Date::VoidYear() {
33 year.reset(); 44 year.reset();
34 } 45 }
35 46
36 void Date::VoidMonth() { 47 void Date::VoidMonth() {
40 void Date::VoidDay() { 51 void Date::VoidDay() {
41 day.reset(); 52 day.reset();
42 } 53 }
43 54
44 void Date::SetYear(unsigned int y) { 55 void Date::SetYear(unsigned int y) {
45 year.reset(new unsigned int(y)); 56 year.emplace(y);
46 } 57 }
47 58
48 void Date::SetMonth(unsigned int m) { 59 void Date::SetMonth(unsigned int m) {
49 month.reset(new unsigned int(CLAMP(m, 1U, 12U))); 60 month.emplace(std::clamp(m, 1U, 12U));
50 } 61 }
51 62
52 void Date::SetDay(unsigned int d) { 63 void Date::SetDay(unsigned int d) {
53 day.reset(new unsigned int(CLAMP(d, 1U, 31U))); 64 day.emplace(std::clamp(d, 1U, 31U));
54 } 65 }
55 66
56 unsigned int Date::GetYear() const { 67 std::optional<unsigned int> Date::GetYear() const {
57 unsigned int* ptr = year.get(); 68 return year;
58 if (ptr != nullptr)
59 return *year;
60 return -1;
61 } 69 }
62 70
63 unsigned int Date::GetMonth() const { 71 std::optional<unsigned int> Date::GetMonth() const {
64 unsigned int* ptr = month.get(); 72 return month;
65 if (ptr != nullptr)
66 return *month;
67 return -1;
68 } 73 }
69 74
70 unsigned int Date::GetDay() const { 75 std::optional<unsigned int> Date::GetDay() const {
71 unsigned int* ptr = day.get(); 76 return day;
72 if (ptr != nullptr)
73 return *day;
74 return -1;
75 } 77 }
76 78
77 bool Date::IsValid() const { 79 bool Date::IsValid() const {
78 return year.get() && month.get() && day.get(); 80 return year.has_value() && month.has_value() && day.has_value();
79 }
80
81 bool Date::operator<(const Date& other) const {
82 unsigned int y = GetYear(), m = GetMonth(), d = GetDay();
83 unsigned int o_y = other.GetYear(), o_m = other.GetMonth(), o_d = other.GetDay();
84 return std::tie(y, m, d) < std::tie(o_y, o_m, o_d);
85 }
86
87 bool Date::operator>(const Date& other) const {
88 return other < (*this);
89 }
90
91 bool Date::operator<=(const Date& other) const {
92 return !((*this) > other);
93 }
94
95 bool Date::operator>=(const Date& other) const {
96 return !((*this) < other);
97 } 81 }
98 82
99 QDate Date::GetAsQDate() const { 83 QDate Date::GetAsQDate() const {
100 /* QDates don't support "missing" values, for good reason. */ 84 /* QDate doesn't support "missing" values (for good reason),
101 if (IsValid()) 85 * so we do our best and return what we can.
102 return QDate(*year, *month, *day); 86 */
103 else 87
104 return QDate(); 88 return QDate(year.value_or(2000), month.value_or(1), day.value_or(1));
105 } 89 }
106 90
107 nlohmann::json Date::GetAsAniListJson() const { 91 nlohmann::json Date::GetAsAniListJson() const {
108 nlohmann::json result = {}; 92 return {
109 if (year.get()) 93 {"year", year},
110 result["year"] = *year; 94 {"month", month},
111 else 95 {"day", day}
112 result["year"] = nullptr; 96 };
113 if (month.get())
114 result["month"] = *month;
115 else
116 result["month"] = nullptr;
117 if (day.get())
118 result["day"] = *day;
119 else
120 result["day"] = nullptr;
121 return result;
122 } 97 }