shakmaty/
util.rs

1use core::{
2    array::TryFromSliceError,
3    convert::TryFrom as _,
4    fmt::{self, Write as _},
5    num::TryFromIntError,
6};
7
8use arrayvec::ArrayString;
9
10#[cold]
11pub(crate) fn out_of_range_error() -> TryFromIntError {
12    // Construct TryFromIntError despite its private constructor.
13    // The standard library keeps it private intentionally,
14    // to be able to provide error details in the future, but it is unlikely
15    // that something more specific than "overflow" will be added.
16    u32::try_from(u64::MAX).unwrap_err()
17}
18
19#[cold]
20pub(crate) fn try_from_slice_error() -> TryFromSliceError {
21    // Construct TryFromSliceError despite its private constructor.
22    // The standard library keeps it private intentionally,
23    // to be able to provide error details in the future, but it is unlikely
24    // that will really happen.
25    <[u8; 0]>::try_from(&[0u8][..]).unwrap_err()
26}
27
28macro_rules! from_enum_as_int_impl {
29    ($from:ty, $($t:ident)+) => {
30        $(impl From<$from> for $t {
31            #[inline]
32            fn from(value: $from) -> $t {
33                value as $t
34            }
35        })+
36    }
37}
38
39pub(crate) trait AppendAscii {
40    type Error;
41
42    fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error>;
43    fn reserve(&mut self, additional: usize);
44
45    fn append_u32(&mut self, n: u32) -> Result<(), Self::Error> {
46        if n >= 1_000_000_000 {
47            self.append_ascii(char::from(b'0' + ((n / 1_000_000_000) % 10) as u8))?;
48        }
49        if n >= 100_000_000 {
50            self.append_ascii(char::from(b'0' + ((n / 100_000_000) % 10) as u8))?;
51        }
52        if n >= 10_000_000 {
53            self.append_ascii(char::from(b'0' + ((n / 10_000_000) % 10) as u8))?;
54        }
55        if n >= 1_000_000 {
56            self.append_ascii(char::from(b'0' + ((n / 1_000_000) % 10) as u8))?;
57        }
58        if n >= 100_000 {
59            self.append_ascii(char::from(b'0' + ((n / 100_000) % 10) as u8))?;
60        }
61        if n >= 10_000 {
62            self.append_ascii(char::from(b'0' + ((n / 10_000) % 10) as u8))?;
63        }
64        if n >= 1_000 {
65            self.append_ascii(char::from(b'0' + ((n / 1_000) % 10) as u8))?;
66        }
67        if n >= 100 {
68            self.append_ascii(char::from(b'0' + ((n / 100) % 10) as u8))?;
69        }
70        if n >= 10 {
71            self.append_ascii(char::from(b'0' + ((n / 10) % 10) as u8))?;
72        }
73        self.append_ascii(char::from(b'0' + (n % 10) as u8))
74    }
75}
76
77impl AppendAscii for fmt::Formatter<'_> {
78    type Error = fmt::Error;
79
80    fn reserve(&mut self, _additional: usize) {}
81
82    fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
83        self.write_char(ascii_char)
84    }
85}
86
87impl<const CAP: usize> AppendAscii for ArrayString<CAP> {
88    type Error = core::convert::Infallible;
89
90    fn reserve(&mut self, _additional: usize) {}
91
92    fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
93        self.push(ascii_char);
94        Ok(())
95    }
96}
97
98#[cfg(feature = "alloc")]
99impl AppendAscii for alloc::string::String {
100    type Error = core::convert::Infallible;
101
102    fn reserve(&mut self, additional: usize) {
103        self.reserve(additional);
104    }
105
106    fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
107        self.push(ascii_char);
108        Ok(())
109    }
110}
111
112#[cfg(feature = "alloc")]
113impl AppendAscii for alloc::vec::Vec<u8> {
114    type Error = core::convert::Infallible;
115
116    fn reserve(&mut self, additional: usize) {
117        self.reserve(additional);
118    }
119
120    fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
121        self.push(ascii_char as u8);
122        Ok(())
123    }
124}