1macro_rules! __impl_assign {
5 ($sym:tt $op:ident $fn:ident $target:ty : $($(#[$attr:meta])* $t:ty),+) => {$(
6 #[allow(unused_qualifications)]
7 $(#[$attr])*
8 impl core::ops::$op<$t> for $target {
9 fn $fn(&mut self, rhs: $t) {
10 *self = *self $sym rhs;
11 }
12 }
13 )+};
14}
15
16macro_rules! impl_add_assign {
18 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
19 $crate::internal_macros::__impl_assign!(
20 + AddAssign add_assign $target : $($(#[$attr])* $t),+
21 );
22 };
23}
24
25macro_rules! impl_sub_assign {
27 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
28 $crate::internal_macros::__impl_assign!(
29 - SubAssign sub_assign $target : $($(#[$attr])* $t),+
30 );
31 };
32}
33
34macro_rules! impl_mul_assign {
36 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
37 $crate::internal_macros::__impl_assign!(
38 * MulAssign mul_assign $target : $($(#[$attr])* $t),+
39 );
40 };
41}
42
43macro_rules! impl_div_assign {
45 ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
46 $crate::internal_macros::__impl_assign!(
47 / DivAssign div_assign $target : $($(#[$attr])* $t),+
48 );
49 };
50}
51
52macro_rules! div_floor {
54 ($a:expr, $b:expr) => {{
55 let _a = $a;
56 let _b = $b;
57
58 let (_quotient, _remainder) = (_a / _b, _a % _b);
59
60 if (_remainder > 0 && _b < 0) || (_remainder < 0 && _b > 0) {
61 _quotient - 1
62 } else {
63 _quotient
64 }
65 }};
66}
67
68macro_rules! cascade {
70 (@ordinal ordinal) => {};
71 (@year year) => {};
72
73 ($from:ident in $min:literal.. $max:expr => $to:tt) => {
75 #[allow(unused_comparisons, unused_assignments)]
76 let min = $min;
77 let max = $max;
78 if $from >= max {
79 $from -= max - min;
80 $to += 1;
81 } else if $from < min {
82 $from += max - min;
83 $to -= 1;
84 }
85 };
86
87 ($ordinal:ident => $year:ident) => {
89 cascade!(@ordinal $ordinal);
91 cascade!(@year $year);
92 #[allow(unused_assignments)]
93 if $ordinal > crate::util::days_in_year($year) as i16 {
94 $ordinal -= crate::util::days_in_year($year) as i16;
95 $year += 1;
96 } else if $ordinal < 1 {
97 $year -= 1;
98 $ordinal += crate::util::days_in_year($year) as i16;
99 }
100 };
101}
102
103macro_rules! ensure_ranged {
105 ($type:ident : $value:ident) => {
106 match $type::new($value) {
107 Some(val) => val,
108 None => {
109 #[allow(trivial_numeric_casts)]
110 return Err(crate::error::ComponentRange {
111 name: stringify!($value),
112 minimum: $type::MIN.get() as _,
113 maximum: $type::MAX.get() as _,
114 value: $value as _,
115 conditional_message: None,
116 });
117 }
118 }
119 };
120
121 ($type:ident : $value:ident $(as $as_type:ident)? * $factor:expr) => {
122 match ($value $(as $as_type)?).checked_mul($factor) {
123 Some(val) => match $type::new(val) {
124 Some(val) => val,
125 None => {
126 #[allow(trivial_numeric_casts)]
127 return Err(crate::error::ComponentRange {
128 name: stringify!($value),
129 minimum: $type::MIN.get() as i64 / $factor as i64,
130 maximum: $type::MAX.get() as i64 / $factor as i64,
131 value: $value as _,
132 conditional_message: None,
133 });
134 }
135 },
136 None => {
137 return Err(crate::error::ComponentRange {
138 name: stringify!($value),
139 minimum: $type::MIN.get() as i64 / $factor as i64,
140 maximum: $type::MAX.get() as i64 / $factor as i64,
141 value: $value as _,
142 conditional_message: None,
143 });
144 }
145 }
146 };
147}
148
149macro_rules! const_try {
154 ($e:expr) => {
155 match $e {
156 Ok(value) => value,
157 Err(error) => return Err(error),
158 }
159 };
160}
161
162macro_rules! const_try_opt {
166 ($e:expr) => {
167 match $e {
168 Some(value) => value,
169 None => return None,
170 }
171 };
172}
173
174macro_rules! expect_opt {
178 ($e:expr, $message:literal) => {
179 match $e {
180 Some(value) => value,
181 None => crate::expect_failed($message),
182 }
183 };
184}
185
186#[cfg(any(feature = "formatting", feature = "parsing"))]
188macro_rules! bug {
189 () => { compile_error!("provide an error message to help fix a possible bug") };
190 ($descr:literal $($rest:tt)?) => {
191 panic!(concat!("internal error: ", $descr) $($rest)?)
192 }
193}
194
195#[cfg(any(feature = "formatting", feature = "parsing"))]
196pub(crate) use bug;
197pub(crate) use {
198 __impl_assign, cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt,
199 impl_add_assign, impl_div_assign, impl_mul_assign, impl_sub_assign,
200};