lean_string/
traits.rs

1use crate::{LeanString, ToLeanStringError, UnwrapWithMsg, repr::Repr};
2use alloc::string::String;
3use castaway::{LifetimeFree, match_type};
4use core::{fmt, fmt::Write, num::NonZero};
5
6/// A trait for converting a value to a [`LeanString`].
7pub trait ToLeanString {
8    /// Converts the value to a [`LeanString`].
9    ///
10    /// # Panics
11    ///
12    /// Panics if conversion fails. For a non-panicking version, use [`try_to_lean_string`].
13    ///
14    /// [`try_to_lean_string`]: Self::try_to_lean_string
15    fn to_lean_string(&self) -> LeanString {
16        self.try_to_lean_string().unwrap_with_msg()
17    }
18
19    /// Attempts to convert the value to a [`LeanString`].
20    ///
21    /// # Errors
22    ///
23    /// Returns a [`ToLeanStringError`] if the conversion fails.
24    fn try_to_lean_string(&self) -> Result<LeanString, ToLeanStringError>;
25}
26
27// NOTE: the restriction of `castaway` is `T` must be Sized.
28impl<T: fmt::Display> ToLeanString for T {
29    fn try_to_lean_string(&self) -> Result<LeanString, ToLeanStringError> {
30        let repr = match_type!(self, {
31            &i8 as s => Repr::from_num(*s)?,
32            &u8 as s => Repr::from_num(*s)?,
33            &i16 as s => Repr::from_num(*s)?,
34            &u16 as s => Repr::from_num(*s)?,
35            &i32 as s => Repr::from_num(*s)?,
36            &u32 as s => Repr::from_num(*s)?,
37            &i64 as s => Repr::from_num(*s)?,
38            &u64 as s => Repr::from_num(*s)?,
39            &i128 as s => Repr::from_num(*s)?,
40            &u128 as s => Repr::from_num(*s)?,
41            &isize as s => Repr::from_num(*s)?,
42            &usize as s => Repr::from_num(*s)?,
43
44            &NonZero<i8> as s => Repr::from_num(*s)?,
45            &NonZero<u8> as s => Repr::from_num(*s)?,
46            &NonZero<i16> as s => Repr::from_num(*s)?,
47            &NonZero<u16> as s => Repr::from_num(*s)?,
48            &NonZero<i32> as s => Repr::from_num(*s)?,
49            &NonZero<u32> as s => Repr::from_num(*s)?,
50            &NonZero<i64> as s => Repr::from_num(*s)?,
51            &NonZero<u64> as s => Repr::from_num(*s)?,
52            &NonZero<i128> as s => Repr::from_num(*s)?,
53            &NonZero<u128> as s => Repr::from_num(*s)?,
54            &NonZero<isize> as s => Repr::from_num(*s)?,
55            &NonZero<usize> as s => Repr::from_num(*s)?,
56
57            &f32 as s => Repr::from_num(*s)?,
58            &f64 as s => Repr::from_num(*s)?,
59
60            &bool as s => Repr::from_bool(*s),
61            &char as s => Repr::from_char(*s),
62
63            &String as s => Repr::from_str(s.as_str())?,
64            &LeanString as s => return Ok(s.clone()),
65
66            s => {
67                let mut buf = LeanString::new();
68                write!(buf, "{}", s)?;
69                return Ok(buf)
70            }
71        });
72        Ok(LeanString(repr))
73    }
74}
75
76// SAFETY:
77// - `LeanString` is `'static`.
78// - `LeanString` does not contain any lifetime parameter.
79// These two conditions are also applied to `Repr` which is the only field of `LeanString`.
80unsafe impl LifetimeFree for LeanString {}
81unsafe impl LifetimeFree for Repr {}