use alloc::borrow::Cow;
use core::hash::Hash;
mod scalar;
mod values;
pub use scalar::Scalar;
pub use values::BTreeValues;
#[cfg(feature = "std")]
pub use values::HashValues;
pub trait Values<'v, 's> {
fn var(&self, name: &str) -> Option<Cow<'_, Value<'v, 's>>>;
}
pub trait ToValue<'v, 's> {
fn to_value(&self) -> Value<'v, 's>;
}
impl<'v, 's: 'v, T> ToValue<'v, 's> for T
where
T: Into<Value<'v, 's>> + Clone,
{
#[inline]
fn to_value(&self) -> Value<'v, 's> {
self.clone().into()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Value<'v, 's: 'v> {
Scalar(Scalar<'v>),
List(Cow<'v, [Scalar<'s>]>),
Keys(Cow<'v, [(Scalar<'s>, Scalar<'s>)]>),
}
impl Value<'_, '_> {
pub fn into_static(self) -> Value<'static, 'static> {
match self {
Self::Scalar(s) => Value::Scalar(s.into_static()),
Self::List(list) => Value::List(Cow::Owned(
list.into_owned()
.into_iter()
.map(|s| s.into_static())
.collect(),
)),
Self::Keys(items) => Value::Keys(Cow::Owned(
items
.into_owned()
.into_iter()
.map(|(k, v)| (k.into_static(), v.into_static()))
.collect(),
)),
}
}
pub(crate) fn should_expand(&self) -> bool {
match self {
Self::Scalar(_) => true,
Self::List(s) => !s.is_empty(),
Self::Keys(items) => !items.is_empty(),
}
}
}
#[cfg(feature = "serde")]
pub use serde_impl::deserialize_owned_value;
#[cfg(feature = "serde")]
mod serde_impl {
use alloc::borrow::Cow;
use core::marker::PhantomData;
use super::{Scalar, Value};
use serde::{Deserialize, de::Visitor};
pub fn deserialize_owned_value<'de, D>(
deserializer: D,
) -> Result<Value<'static, 'static>, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer
.deserialize_any(ValueVisitor(PhantomData))
.map(move |v| v.into_static())
}
pub struct ScalarValueVisitor<'a>(PhantomData<&'a ()>);
impl<'de: 'a, 'a> Deserialize<'de> for Scalar<'a> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(ScalarValueVisitor(PhantomData))
}
}
impl<'de: 'a, 'a> Visitor<'de> for ScalarValueVisitor<'a> {
type Value = Scalar<'a>;
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter
.write_str("a string/number/boolean, list of value, or list of key-value pairs")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.to_owned().into()))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(Cow::Borrowed(v)))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.into()))
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(Cow::Owned(v.to_string())))
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.to_string().into()))
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.to_string().into()))
}
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.to_string().into()))
}
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.to_string().into()))
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Scalar(v.to_string().into()))
}
}
pub struct ValueVisitor<'v, 's: 'v>(PhantomData<(&'v (), &'s ())>);
impl<'de: 'v + 's, 'v, 's: 'v> Deserialize<'de> for Value<'v, 's> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor(PhantomData))
}
}
impl<'de: 'v + 's, 'v, 's: 'v> Visitor<'de> for ValueVisitor<'v, 's> {
type Value = Value<'v, 'v>;
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter
.write_str("a string/number/boolean, list of value, or list of key-value pairs")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut values = Vec::new();
while let Some(value) = seq.next_element::<Scalar<'v>>()? {
values.push(value);
}
Ok(Value::List(Cow::Owned(values)))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut items = Vec::new();
while let Some((key, value)) = map.next_entry::<Scalar<'v>, Scalar<'v>>()? {
items.push((key, value));
}
Ok(Value::Keys(Cow::Owned(items)))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_str(v)
.map(Value::Scalar)
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_string(v)
.map(Value::Scalar)
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_borrowed_str(v)
.map(Value::Scalar)
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_bool(v)
.map(Value::Scalar)
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_i64(v)
.map(Value::Scalar)
}
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_i128(v)
.map(Value::Scalar)
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_u64(v)
.map(Value::Scalar)
}
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_u128(v)
.map(Value::Scalar)
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
ScalarValueVisitor(PhantomData)
.visit_f64(v)
.map(Value::Scalar)
}
}
}