use super::Value;
use alloc::{borrow::Cow, string::String};
use core::{hash::Hash, ops::Deref};
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Scalar<'a>(pub(crate) Cow<'a, str>);
impl<'a> Scalar<'a> {
pub fn into_static(self) -> Scalar<'static> {
Scalar(Cow::Owned(self.0.into_owned()))
}
}
impl<'a> Deref for Scalar<'a> {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> From<&'a str> for Scalar<'a> {
fn from(value: &'a str) -> Self {
Self(Cow::Borrowed(value))
}
}
impl<'a> From<String> for Scalar<'a> {
fn from(value: String) -> Self {
Self(Cow::Owned(value))
}
}
macro_rules! impl_from_display_for_scalar {
($($ty:ty),+ $(,)?) => {
$(
impl<'a> From<$ty> for Scalar<'a> {
fn from(value: $ty) -> Self {
Scalar(Cow::Owned(value.to_string()))
}
}
)+
};
}
impl_from_display_for_scalar!(i8, i16, i32, i64, i128);
impl_from_display_for_scalar!(u8, u16, u32, u64, u128);
impl_from_display_for_scalar!(bool);
#[cfg(feature = "std")]
impl_from_display_for_scalar!(std::net::IpAddr);
impl<'v, 's: 'v, T> From<T> for Value<'v, 's>
where
T: Into<Scalar<'v>>,
{
fn from(value: T) -> Self {
Self::Scalar(value.into())
}
}
impl<'v, 's: 'v, T> From<&'v [T]> for Value<'v, 's>
where
&'v T: Into<Scalar<'s>>,
{
fn from(value: &'v [T]) -> Self {
let value = value.iter().map(Into::into).collect();
Self::List(Cow::Owned(value))
}
}
impl<'v, 's: 'v, T, const N: usize> From<[T; N]> for Value<'v, 's>
where
[T; N]: 'v,
T: Into<Scalar<'s>>,
{
fn from(value: [T; N]) -> Self {
let value = value.map(Into::into).to_vec();
Self::List(Cow::Owned(value))
}
}
impl<'v, 's: 'v, T> From<Vec<T>> for Value<'v, 's>
where
T: Into<Scalar<'s>>,
{
fn from(value: Vec<T>) -> Self {
let value = value.into_iter().map(Into::into).collect();
Self::List(Cow::Owned(value))
}
}
impl<'v, 's: 'v, K, V> From<&'v [(K, V)]> for Value<'v, 's>
where
&'v K: Into<Scalar<'s>>,
&'v V: Into<Scalar<'s>>,
{
fn from(value: &'v [(K, V)]) -> Self {
let value = value
.iter()
.map(|(k, v)| (Into::into(k), Into::into(v)))
.collect();
Self::Keys(Cow::Owned(value))
}
}
impl<'v, 's: 'v, K, V, const N: usize> From<[(K, V); N]> for Value<'v, 's>
where
[(K, V); N]: 'v,
K: Into<Scalar<'s>>,
V: Into<Scalar<'s>>,
{
fn from(value: [(K, V); N]) -> Self {
let value = value.map(|(k, v)| (Into::into(k), Into::into(v))).to_vec();
Self::Keys(Cow::Owned(value))
}
}