Skip to main content

uri_template_core/value/
scalar.rs

1use super::Value;
2use alloc::{borrow::Cow, string::String};
3use core::{hash::Hash, ops::Deref};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
6pub struct Scalar<'a>(pub(crate) Cow<'a, str>);
7impl<'a> Scalar<'a> {
8    pub fn into_static(self) -> Scalar<'static> {
9        Scalar(Cow::Owned(self.0.into_owned()))
10    }
11}
12impl<'a> Deref for Scalar<'a> {
13    type Target = str;
14
15    fn deref(&self) -> &Self::Target {
16        &self.0
17    }
18}
19impl<'a> From<&'a str> for Scalar<'a> {
20    fn from(value: &'a str) -> Self {
21        Self(Cow::Borrowed(value))
22    }
23}
24impl<'a> From<String> for Scalar<'a> {
25    fn from(value: String) -> Self {
26        Self(Cow::Owned(value))
27    }
28}
29
30macro_rules! impl_from_display_for_scalar {
31    ($($ty:ty),+ $(,)?) => {
32        $(
33            impl<'a> From<$ty> for Scalar<'a> {
34                fn from(value: $ty) -> Self {
35                    Scalar(Cow::Owned(value.to_string()))
36                }
37            }
38        )+
39    };
40}
41
42impl_from_display_for_scalar!(i8, i16, i32, i64, i128);
43impl_from_display_for_scalar!(u8, u16, u32, u64, u128);
44impl_from_display_for_scalar!(bool);
45#[cfg(feature = "std")]
46impl_from_display_for_scalar!(std::net::IpAddr);
47
48impl<'v, 's: 'v, T> From<T> for Value<'v, 's>
49where
50    T: Into<Scalar<'v>>,
51{
52    fn from(value: T) -> Self {
53        Self::Scalar(value.into())
54    }
55}
56
57impl<'v, 's: 'v, T> From<&'v [T]> for Value<'v, 's>
58where
59    &'v T: Into<Scalar<'s>>,
60{
61    fn from(value: &'v [T]) -> Self {
62        let value = value.iter().map(Into::into).collect();
63        Self::List(Cow::Owned(value))
64    }
65}
66
67impl<'v, 's: 'v, T, const N: usize> From<[T; N]> for Value<'v, 's>
68where
69    [T; N]: 'v,
70    T: Into<Scalar<'s>>,
71{
72    fn from(value: [T; N]) -> Self {
73        let value = value.map(Into::into).to_vec();
74        Self::List(Cow::Owned(value))
75    }
76}
77
78impl<'v, 's: 'v, T> From<Vec<T>> for Value<'v, 's>
79where
80    T: Into<Scalar<'s>>,
81{
82    fn from(value: Vec<T>) -> Self {
83        let value = value.into_iter().map(Into::into).collect();
84        Self::List(Cow::Owned(value))
85    }
86}
87
88impl<'v, 's: 'v, K, V> From<&'v [(K, V)]> for Value<'v, 's>
89where
90    &'v K: Into<Scalar<'s>>,
91    &'v V: Into<Scalar<'s>>,
92{
93    fn from(value: &'v [(K, V)]) -> Self {
94        let value = value
95            .iter()
96            .map(|(k, v)| (Into::into(k), Into::into(v)))
97            .collect();
98        Self::Keys(Cow::Owned(value))
99    }
100}
101
102impl<'v, 's: 'v, K, V, const N: usize> From<[(K, V); N]> for Value<'v, 's>
103where
104    [(K, V); N]: 'v,
105    K: Into<Scalar<'s>>,
106    V: Into<Scalar<'s>>,
107{
108    fn from(value: [(K, V); N]) -> Self {
109        let value = value.map(|(k, v)| (Into::into(k), Into::into(v))).to_vec();
110        Self::Keys(Cow::Owned(value))
111    }
112}