use core::{
array::TryFromSliceError,
convert::TryFrom as _,
fmt::{self, Write as _},
num::TryFromIntError,
};
use arrayvec::ArrayString;
#[cold]
pub(crate) fn out_of_range_error() -> TryFromIntError {
u32::try_from(u64::MAX).unwrap_err()
}
#[cold]
pub(crate) fn try_from_slice_error() -> TryFromSliceError {
<[u8; 0]>::try_from(&[0u8][..]).unwrap_err()
}
macro_rules! from_enum_as_int_impl {
($from:ty, $($t:ident)+) => {
$(impl From<$from> for $t {
#[inline]
fn from(value: $from) -> $t {
value as $t
}
})+
}
}
pub(crate) trait AppendAscii {
type Error;
fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error>;
fn reserve(&mut self, additional: usize);
fn append_u32(&mut self, n: u32) -> Result<(), Self::Error> {
if n >= 1_000_000_000 {
self.append_ascii(char::from(b'0' + ((n / 1_000_000_000) % 10) as u8))?;
}
if n >= 100_000_000 {
self.append_ascii(char::from(b'0' + ((n / 100_000_000) % 10) as u8))?;
}
if n >= 10_000_000 {
self.append_ascii(char::from(b'0' + ((n / 10_000_000) % 10) as u8))?;
}
if n >= 1_000_000 {
self.append_ascii(char::from(b'0' + ((n / 1_000_000) % 10) as u8))?;
}
if n >= 100_000 {
self.append_ascii(char::from(b'0' + ((n / 100_000) % 10) as u8))?;
}
if n >= 10_000 {
self.append_ascii(char::from(b'0' + ((n / 10_000) % 10) as u8))?;
}
if n >= 1_000 {
self.append_ascii(char::from(b'0' + ((n / 1_000) % 10) as u8))?;
}
if n >= 100 {
self.append_ascii(char::from(b'0' + ((n / 100) % 10) as u8))?;
}
if n >= 10 {
self.append_ascii(char::from(b'0' + ((n / 10) % 10) as u8))?;
}
self.append_ascii(char::from(b'0' + (n % 10) as u8))
}
}
impl AppendAscii for fmt::Formatter<'_> {
type Error = fmt::Error;
fn reserve(&mut self, _additional: usize) {}
fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
self.write_char(ascii_char)
}
}
impl<const CAP: usize> AppendAscii for ArrayString<CAP> {
type Error = core::convert::Infallible;
fn reserve(&mut self, _additional: usize) {}
fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
self.push(ascii_char);
Ok(())
}
}
#[cfg(feature = "alloc")]
impl AppendAscii for alloc::string::String {
type Error = core::convert::Infallible;
fn reserve(&mut self, additional: usize) {
self.reserve(additional);
}
fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
self.push(ascii_char);
Ok(())
}
}
#[cfg(feature = "alloc")]
impl AppendAscii for alloc::vec::Vec<u8> {
type Error = core::convert::Infallible;
fn reserve(&mut self, additional: usize) {
self.reserve(additional);
}
fn append_ascii(&mut self, ascii_char: char) -> Result<(), Self::Error> {
self.push(ascii_char as u8);
Ok(())
}
}