Coverage Report

Created: 2025-09-05 06:11

/rust/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.43/src/internal_macros.rs
Line
Count
Source (jump to first uncovered line)
1
//! Macros for use within the library. They are not publicly available.
2
3
/// Helper macro for easily implementing `OpAssign`.
4
macro_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
            #[inline]
10
0
            fn $fn(&mut self, rhs: $t) {
11
0
                *self = *self $sym rhs;
12
0
            }
Unexecuted instantiation: <time::date::Date as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::date::Date as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::date::Date as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::date::Date as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::AddAssign>::add_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::SubAssign>::sub_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<i8>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<i16>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<i32>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<u8>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<u16>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<u32>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<f32>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::MulAssign<f64>>::mul_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<i8>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<i16>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<i32>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<u8>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<u16>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<u32>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<f32>>::div_assign
Unexecuted instantiation: <time::duration::Duration as core::ops::arith::DivAssign<f64>>::div_assign
Unexecuted instantiation: <std::time::SystemTime as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <std::time::SystemTime as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <std::time::Instant as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::instant::Instant as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
Unexecuted instantiation: <std::time::Instant as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::AddAssign<time::duration::Duration>>::add_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::AddAssign<core::time::Duration>>::add_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::SubAssign<time::duration::Duration>>::sub_assign
Unexecuted instantiation: <time::time::Time as core::ops::arith::SubAssign<core::time::Duration>>::sub_assign
13
        }
14
    )+};
15
}
16
17
/// Implement `AddAssign` for the provided types.
18
macro_rules! impl_add_assign {
19
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
20
        $crate::internal_macros::__impl_assign!(
21
            + AddAssign add_assign $target : $($(#[$attr])* $t),+
22
        );
23
    };
24
}
25
26
/// Implement `SubAssign` for the provided types.
27
macro_rules! impl_sub_assign {
28
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
29
        $crate::internal_macros::__impl_assign!(
30
            - SubAssign sub_assign $target : $($(#[$attr])* $t),+
31
        );
32
    };
33
}
34
35
/// Implement `MulAssign` for the provided types.
36
macro_rules! impl_mul_assign {
37
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
38
        $crate::internal_macros::__impl_assign!(
39
            * MulAssign mul_assign $target : $($(#[$attr])* $t),+
40
        );
41
    };
42
}
43
44
/// Implement `DivAssign` for the provided types.
45
macro_rules! impl_div_assign {
46
    ($target:ty : $($(#[$attr:meta])* $t:ty),+ $(,)?) => {
47
        $crate::internal_macros::__impl_assign!(
48
            / DivAssign div_assign $target : $($(#[$attr])* $t),+
49
        );
50
    };
51
}
52
53
/// Division of integers, rounding the resulting value towards negative infinity.
54
macro_rules! div_floor {
55
    ($self:expr, $rhs:expr) => {
56
        match ($self, $rhs) {
57
            (this, rhs) => {
58
                let d = this / rhs;
59
                let r = this % rhs;
60
61
                // If the remainder is non-zero, we need to subtract one if the
62
                // signs of self and rhs differ, as this means we rounded upwards
63
                // instead of downwards. We do this branchlessly by creating a mask
64
                // which is all-ones iff the signs differ, and 0 otherwise. Then by
65
                // adding this mask (which corresponds to the signed value -1), we
66
                // get our correction.
67
                let correction = (this ^ rhs) >> ($crate::size_of_val(&this) * 8 - 1);
68
                if r != 0 {
69
                    d + correction
70
                } else {
71
                    d
72
                }
73
            }
74
        }
75
    };
76
}
77
78
/// Similar to `overflowing_add`, but returning the number of times that it overflowed. Contained to
79
/// a certain range and only overflows a maximum number of times.
80
macro_rules! carry {
81
    (@most_once $value:expr, $min:literal.. $max:expr) => {
82
        match ($value, $min, $max) {
83
            (value, min, max) => {
84
                if crate::hint::likely(value >= min) {
85
                    if crate::hint::likely(value < max) {
86
                        (value, 0)
87
                    } else {
88
                        (value - (max - min), 1)
89
                    }
90
                } else {
91
                    (value + (max - min), -1)
92
                }
93
            }
94
        }
95
    };
96
    (@most_twice $value:expr, $min:literal.. $max:expr) => {
97
        match ($value, $min, $max) {
98
            (value, min, max) => {
99
                if crate::hint::likely(value >= min) {
100
                    if crate::hint::likely(value < max) {
101
                        (value, 0)
102
                    } else if value < 2 * max - min {
103
                        (value - (max - min), 1)
104
                    } else {
105
                        (value - 2 * (max - min), 2)
106
                    }
107
                } else {
108
                    if value >= min - max {
109
                        (value + (max - min), -1)
110
                    } else {
111
                        (value + 2 * (max - min), -2)
112
                    }
113
                }
114
            }
115
        }
116
    };
117
    (@most_thrice $value:expr, $min:literal.. $max:expr) => {
118
        match ($value, $min, $max) {
119
            (value, min, max) => {
120
                if crate::hint::likely(value >= min) {
121
                    if crate::hint::likely(value < max) {
122
                        (value, 0)
123
                    } else if value < 2 * max - min {
124
                        (value - (max - min), 1)
125
                    } else if value < 3 * max - 2 * min {
126
                        (value - 2 * (max - min), 2)
127
                    } else {
128
                        (value - 3 * (max - min), 3)
129
                    }
130
                } else {
131
                    if value >= min - max {
132
                        (value + (max - min), -1)
133
                    } else if value >= 2 * (min - max) {
134
                        (value + 2 * (max - min), -2)
135
                    } else {
136
                        (value + 3 * (max - min), -3)
137
                    }
138
                }
139
            }
140
        }
141
    };
142
}
143
144
/// Cascade an out-of-bounds value.
145
macro_rules! cascade {
146
    (@ordinal ordinal) => {};
147
    (@year year) => {};
148
149
    // Cascade an out-of-bounds value from "from" to "to".
150
    ($from:ident in $min:literal.. $max:expr => $to:tt) => {
151
        #[allow(unused_comparisons, unused_assignments)]
152
        let min = $min;
153
        let max = $max;
154
        if crate::hint::unlikely($from >= max) {
155
            $from -= max - min;
156
            $to += 1;
157
        } else if crate::hint::unlikely($from < min) {
158
            $from += max - min;
159
            $to -= 1;
160
        }
161
    };
162
163
    // Special case the ordinal-to-year cascade, as it has different behavior.
164
    ($ordinal:ident => $year:ident) => {
165
        // We need to actually capture the idents. Without this, macro hygiene causes errors.
166
        cascade!(@ordinal $ordinal);
167
        cascade!(@year $year);
168
169
        let days_in_year = crate::util::days_in_year($year) as i16;
170
        #[allow(unused_assignments)]
171
        if crate::hint::unlikely($ordinal > days_in_year) {
172
            $ordinal -= days_in_year;
173
            $year += 1;
174
        } else if crate::hint::unlikely($ordinal < 1) {
175
            $year -= 1;
176
            $ordinal += crate::util::days_in_year($year) as i16;
177
        }
178
    };
179
}
180
181
/// Constructs a ranged integer, returning a `ComponentRange` error if the value is out of range.
182
macro_rules! ensure_ranged {
183
    ($type:ty : $value:ident) => {
184
        match <$type>::new($value) {
185
            Some(val) => val,
186
            None => {
187
                $crate::hint::cold_path();
188
                #[allow(trivial_numeric_casts)]
189
                return Err(crate::error::ComponentRange {
190
                    name: stringify!($value),
191
                    minimum: <$type>::MIN.get() as i64,
192
                    maximum: <$type>::MAX.get() as i64,
193
                    value: $value as i64,
194
                    conditional_message: None,
195
                });
196
            }
197
        }
198
    };
199
200
    ($type:ty : $value:ident $(as $as_type:ident)? * $factor:expr) => {
201
        match ($value $(as $as_type)?).checked_mul($factor) {
202
            Some(val) => match <$type>::new(val) {
203
                Some(val) => val,
204
                None => {
205
                    $crate::hint::cold_path();
206
                    #[allow(trivial_numeric_casts)]
207
                    return Err(crate::error::ComponentRange {
208
                        name: stringify!($value),
209
                        minimum: <$type>::MIN.get() as i64 / $factor as i64,
210
                        maximum: <$type>::MAX.get() as i64 / $factor as i64,
211
                        value: $value as i64,
212
                        conditional_message: None,
213
                    });
214
                }
215
            },
216
            None => {
217
                $crate::hint::cold_path();
218
                return Err(crate::error::ComponentRange {
219
                    name: stringify!($value),
220
                    minimum: <$type>::MIN.get() as i64 / $factor as i64,
221
                    maximum: <$type>::MAX.get() as i64 / $factor as i64,
222
                    value: $value as i64,
223
                    conditional_message: None,
224
                });
225
            }
226
        }
227
    };
228
}
229
230
/// Try to unwrap an expression, returning if not possible.
231
///
232
/// This is similar to the `?` operator, but does not perform `.into()`. Because of this, it is
233
/// usable in `const` contexts.
234
macro_rules! const_try {
235
    ($e:expr) => {
236
        match $e {
237
            Ok(value) => value,
238
            Err(error) => return Err(error),
239
        }
240
    };
241
}
242
243
/// Try to unwrap an expression, returning if not possible.
244
///
245
/// This is similar to the `?` operator, but is usable in `const` contexts.
246
macro_rules! const_try_opt {
247
    ($e:expr) => {
248
        match $e {
249
            Some(value) => value,
250
            None => return None,
251
        }
252
    };
253
}
254
255
/// Try to unwrap an expression, panicking if not possible.
256
///
257
/// This is similar to `$e.expect($message)`, but is usable in `const` contexts.
258
macro_rules! expect_opt {
259
    ($e:expr, $message:literal) => {
260
        match $e {
261
            Some(value) => value,
262
            None => crate::expect_failed($message),
263
        }
264
    };
265
}
266
267
/// `unreachable!()`, but better.
268
#[cfg(any(feature = "formatting", feature = "parsing"))]
269
macro_rules! bug {
270
    () => { compile_error!("provide an error message to help fix a possible bug") };
271
    ($descr:literal $($rest:tt)?) => {
272
        panic!(concat!("internal error: ", $descr) $($rest)?)
273
    }
274
}
275
276
#[cfg(any(feature = "formatting", feature = "parsing"))]
277
pub(crate) use bug;
278
pub(crate) use {
279
    __impl_assign, carry, cascade, const_try, const_try_opt, div_floor, ensure_ranged, expect_opt,
280
    impl_add_assign, impl_div_assign, impl_mul_assign, impl_sub_assign,
281
};