1use std::{
2 fmt::Debug,
3 ops::{Add, AddAssign, Div},
4};
5
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8use vecdb::{CheckedSub, Formattable, Pco, PrintableIndex};
9
10use super::{Date, DateIndex, YearIndex};
11
12#[derive(
13 Debug,
14 Clone,
15 Copy,
16 PartialEq,
17 Eq,
18 PartialOrd,
19 Ord,
20 Default,
21 Serialize,
22 Deserialize,
23 Pco,
24 JsonSchema,
25)]
26pub struct DecadeIndex(u16);
27
28impl From<u16> for DecadeIndex {
29 #[inline]
30 fn from(value: u16) -> Self {
31 Self(value)
32 }
33}
34
35impl From<DecadeIndex> for u16 {
36 #[inline]
37 fn from(value: DecadeIndex) -> Self {
38 value.0
39 }
40}
41
42impl From<usize> for DecadeIndex {
43 #[inline]
44 fn from(value: usize) -> Self {
45 Self(value as u16)
46 }
47}
48
49impl From<DecadeIndex> for usize {
50 #[inline]
51 fn from(value: DecadeIndex) -> Self {
52 value.0 as usize
53 }
54}
55
56impl Add<usize> for DecadeIndex {
57 type Output = Self;
58
59 fn add(self, rhs: usize) -> Self::Output {
60 Self::from(self.0 + rhs as u16)
61 }
62}
63
64impl Add<DecadeIndex> for DecadeIndex {
65 type Output = Self;
66
67 fn add(self, rhs: Self) -> Self::Output {
68 Self::from(self.0 + rhs.0)
69 }
70}
71
72impl AddAssign for DecadeIndex {
73 fn add_assign(&mut self, rhs: Self) {
74 *self = Self(self.0 + rhs.0)
75 }
76}
77
78impl Div<usize> for DecadeIndex {
79 type Output = Self;
80 fn div(self, _: usize) -> Self::Output {
81 unreachable!()
82 }
83}
84
85impl From<DateIndex> for DecadeIndex {
86 #[inline]
87 fn from(value: DateIndex) -> Self {
88 Self::from(Date::from(value))
89 }
90}
91
92impl From<Date> for DecadeIndex {
93 #[inline]
94 fn from(value: Date) -> Self {
95 let year = value.year();
96 if year < 2000 {
97 panic!("unsupported")
98 }
99 Self((year - 2000) / 10)
100 }
101}
102
103impl CheckedSub for DecadeIndex {
104 fn checked_sub(self, rhs: Self) -> Option<Self> {
105 self.0.checked_sub(rhs.0).map(Self)
106 }
107}
108
109impl From<YearIndex> for DecadeIndex {
110 #[inline]
111 fn from(value: YearIndex) -> Self {
112 let v = usize::from(value);
113 if v == 0 {
114 Self(0)
115 } else {
116 Self((((v - 1) / 10) + 1) as u16)
117 }
118 }
119}
120
121impl PrintableIndex for DecadeIndex {
122 fn to_string() -> &'static str {
123 "decadeindex"
124 }
125
126 fn to_possible_strings() -> &'static [&'static str] {
127 &["decade", "decadeindex"]
128 }
129}
130
131impl std::fmt::Display for DecadeIndex {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 let mut buf = itoa::Buffer::new();
134 let str = buf.format(self.0);
135 f.write_str(str)
136 }
137}
138
139impl Formattable for DecadeIndex {
140 #[inline(always)]
141 fn may_need_escaping() -> bool {
142 false
143 }
144}