tz/utils/
const_fns.rs
1use crate::error::OutOfRangeError;
4use crate::timezone::{LeapSecond, Transition};
5
6use core::cmp::Ordering;
7
8#[cfg_attr(feature = "const", const_fn::const_fn)]
10pub fn cmp(a: i64, b: i64) -> Ordering {
11 if a < b {
12 Ordering::Less
13 } else if a == b {
14 Ordering::Equal
15 } else {
16 Ordering::Greater
17 }
18}
19
20#[cfg_attr(feature = "const", const_fn::const_fn)]
22pub fn min(a: i64, b: i64) -> i64 {
23 match cmp(a, b) {
24 Ordering::Less | Ordering::Equal => a,
25 Ordering::Greater => b,
26 }
27}
28
29macro_rules! impl_try_into_integer {
31 ($from_type:ty, $to_type:ty, $value:expr) => {{
32 let min = <$to_type>::MIN as $from_type;
33 let max = <$to_type>::MAX as $from_type;
34
35 if min <= $value && $value <= max {
36 Ok($value as $to_type)
37 } else {
38 Err(OutOfRangeError("out of range integer conversion"))
39 }
40 }};
41}
42
43#[cfg_attr(feature = "const", const_fn::const_fn)]
45pub fn try_into_i32(value: i64) -> Result<i32, OutOfRangeError> {
46 impl_try_into_integer!(i64, i32, value)
47}
48
49#[cfg_attr(feature = "const", const_fn::const_fn)]
51pub fn try_into_i64(value: i128) -> Result<i64, OutOfRangeError> {
52 impl_try_into_integer!(i128, i64, value)
53}
54
55macro_rules! impl_binary_search {
57 ($slice:expr, $f:expr, $x:expr) => {{
58 let mut size = $slice.len();
59 let mut left = 0;
60 let mut right = size;
61 while left < right {
62 let mid = left + size / 2;
63
64 let v = $f(&$slice[mid]);
65 if v < $x {
66 left = mid + 1;
67 } else if v > $x {
68 right = mid;
69 } else {
70 return Ok(mid);
71 }
72
73 size = right - left;
74 }
75 Err(left)
76 }};
77}
78
79#[cfg_attr(feature = "const", const_fn::const_fn)]
81fn copied(x: &i64) -> i64 {
82 *x
83}
84
85#[cfg_attr(feature = "const", const_fn::const_fn)]
87pub fn binary_search_i64(slice: &[i64], x: i64) -> Result<usize, usize> {
88 impl_binary_search!(slice, copied, x)
89}
90
91#[cfg_attr(feature = "const", const_fn::const_fn)]
93pub fn binary_search_transitions(slice: &[Transition], x: i64) -> Result<usize, usize> {
94 impl_binary_search!(slice, Transition::unix_leap_time, x)
95}
96
97#[cfg_attr(feature = "const", const_fn::const_fn)]
99pub fn binary_search_leap_seconds(slice: &[LeapSecond], x: i64) -> Result<usize, usize> {
100 impl_binary_search!(slice, LeapSecond::unix_leap_time, x)
101}
102
103macro_rules! const_panic {
105 () => {{
106 #[allow(unconditional_panic)]
107 let panic = [][0];
108 panic
109 }};
110}
111pub(crate) use const_panic;