hyperide/
hyper.rs

1use std::{borrow::Cow, ops::Deref};
2
3#[doc(hidden)]
4pub use html_escape::encode_text;
5
6pub struct HyperText<'a> {
7    inner: Cow<'a, str>,
8}
9impl<'a> Deref for HyperText<'a> {
10    type Target = <Cow<'a, str> as Deref>::Target;
11
12    fn deref(&self) -> &Self::Target {
13        self.inner.deref()
14    }
15}
16impl<'a> From<&'a str> for HyperText<'a> {
17    fn from(value: &'a str) -> Self {
18        HyperText {
19            inner: Cow::Borrowed(value),
20        }
21    }
22}
23impl<'a> From<String> for HyperText<'a> {
24    fn from(value: String) -> Self {
25        HyperText {
26            inner: Cow::Owned(value),
27        }
28    }
29}
30impl<'a> Default for HyperText<'a> {
31    fn default() -> Self {
32        Self {
33            inner: Cow::Borrowed(""),
34        }
35    }
36}
37
38pub trait IntoHyperText<'a> {
39    fn into_hyper_text(self) -> HyperText<'a>;
40}
41
42impl<'a> IntoHyperText<'a> for HyperText<'a> {
43    fn into_hyper_text(self) -> HyperText<'a> {
44        self
45    }
46}
47
48macro_rules! impl_to_str {
49    ($t:ty) => {
50        impl<'a> IntoHyperText<'a> for $t {
51            fn into_hyper_text(self) -> HyperText<'a> {
52                self.to_string().into()
53            }
54        }
55    };
56    ($t:ty, $($r:ty),*) => {
57        impl_to_str!($t);
58        impl_to_str!($($r),*);
59    };
60}
61
62impl<'a> IntoHyperText<'a> for &'a str {
63    fn into_hyper_text(self) -> HyperText<'a> {
64        self.into()
65    }
66}
67impl<'a> IntoHyperText<'a> for String {
68    fn into_hyper_text(self) -> HyperText<'a> {
69        self.into()
70    }
71}
72impl<'a> IntoHyperText<'a> for Cow<'a, str> {
73    fn into_hyper_text(self) -> HyperText<'a> {
74        HyperText { inner: self }
75    }
76}
77
78impl_to_str![
79    usize,
80    u8,
81    u16,
82    u32,
83    u64,
84    u128,
85    isize,
86    i8,
87    i16,
88    i32,
89    i64,
90    i128,
91    f32,
92    f64,
93    char,
94    bool,
95    std::net::IpAddr,
96    std::net::SocketAddr,
97    std::net::SocketAddrV4,
98    std::net::SocketAddrV6,
99    std::net::Ipv4Addr,
100    std::net::Ipv6Addr,
101    std::char::ToUppercase,
102    std::char::ToLowercase,
103    std::num::NonZeroI8,
104    std::num::NonZeroU8,
105    std::num::NonZeroI16,
106    std::num::NonZeroU16,
107    std::num::NonZeroI32,
108    std::num::NonZeroU32,
109    std::num::NonZeroI64,
110    std::num::NonZeroU64,
111    std::num::NonZeroI128,
112    std::num::NonZeroU128,
113    std::num::NonZeroIsize,
114    std::num::NonZeroUsize,
115    std::panic::Location<'_>,
116    std::fmt::Arguments<'_>
117];
118
119impl<'a, T> IntoHyperText<'a> for Option<T>
120where
121    T: IntoHyperText<'a>,
122{
123    fn into_hyper_text(self) -> HyperText<'a> {
124        self.map(IntoHyperText::into_hyper_text).unwrap_or_default()
125    }
126}