#![cfg_attr(
feature = "tracing",
allow(clippy::used_underscore_binding, reason = "Only used in tracing::instrument")
)]
mod de;
mod ser;
use ::alloc::{
borrow::{Cow, ToOwned},
boxed::Box,
collections::VecDeque,
string::String,
vec::Vec,
};
use ::core::{
fmt::Write,
marker::PhantomData,
ops::{Deref, DerefMut},
};
use ::serde::{Deserialize, Serialize};
use crate::{Config, Result};
#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(value)))]
pub fn to_value_with_config<T>(value: &T, config: Config) -> Result<Value<'static>>
where
T: Serialize,
{
let ser = ser::ValueSerializer::new(config.use_indices);
value.serialize(ser)
}
pub fn to_value<T>(value: &T) -> Result<Value<'static>>
where
T: Serialize,
{
to_value_with_config(value, Config::default())
}
#[cfg_attr(feature = "tracing", ::tracing::instrument(skip(value)))]
pub fn from_value_with_config<'de, T>(value: Value<'de>, _config: Config) -> Result<T>
where
T: Deserialize<'de>,
{
let de = de::ValueDeserializer::new(value);
T::deserialize(de)
}
pub fn from_value<'de, T>(value: Value<'de>) -> Result<T>
where
T: Deserialize<'de>,
{
from_value_with_config(value, Config::default())
}
#[derive(Debug, Clone, Default)]
pub enum Value<'a> {
#[default]
Null,
Bool(bool),
Integer(Integer),
Float(Float),
Bytes(Cow<'a, [u8]>),
String(Cow<'a, str>),
Array(VecDeque<Self>),
Map(VecDeque<(Self, Self)>),
}
#[derive(Debug, Clone, Default)]
pub struct OwnedValue(Value<'static>);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Integer {
Unsigned(u128),
Signed(i128),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Float {
F32(f32),
F64(f64),
}
impl<'a> Value<'a> {
pub fn borrow_clone(&self) -> Value<'_> {
match self {
Value::Null => Value::Null,
Value::Bool(b) => Value::Bool(*b),
Value::Integer(int) => Value::Integer(*int),
Value::Float(float) => Value::Float(*float),
Value::Bytes(bytes) => Value::Bytes(Cow::Borrowed(bytes)),
Value::String(s) => Value::String(Cow::Borrowed(s)),
Value::Array(arr) => Value::Array(arr.iter().map(Self::borrow_clone).collect()),
Value::Map(map) => Value::Map(
map.iter().map(|(key, value)| (key.borrow_clone(), value.borrow_clone())).collect(),
),
}
}
#[must_use]
pub fn into_owned(self) -> OwnedValue {
let value = match self {
Value::Null => Value::Null,
Value::Bool(b) => Value::Bool(b),
Value::Integer(int) => Value::Integer(int),
Value::Float(float) => Value::Float(float),
Value::Bytes(bytes) => Value::Bytes(bytes.into_owned().into()),
Value::String(s) => Value::String(s.into_owned().into()),
Value::Array(arr) => Value::Array(arr.into_iter().map(|v| v.into_owned().0).collect()),
Value::Map(map) => Value::Map(
map.into_iter()
.map(|(key, value)| (key.into_owned().0, value.into_owned().0))
.collect(),
),
};
OwnedValue(value)
}
#[inline]
pub fn deserialize_as<'de, T>(self) -> Result<T>
where
'a: 'de,
T: Deserialize<'de>,
{
T::deserialize(de::ValueDeserializer::new(self))
}
#[must_use]
#[inline]
pub fn is_empty(&self) -> bool {
match self {
Value::Null => true,
Value::Bool(_) | Value::Integer(_) | Value::Float(_) => false,
Value::Bytes(bytes) => bytes.is_empty(),
Value::String(s) => s.is_empty(),
Value::Array(arr) => arr.is_empty(),
Value::Map(map) => map.is_empty(),
}
}
#[must_use]
pub const fn as_bool(&self) -> Option<bool> {
if let Value::Bool(v) = self {
Some(*v)
} else {
None
}
}
#[must_use]
pub const fn as_int(&self) -> Option<Integer> {
if let Value::Integer(v) = self {
Some(*v)
} else {
None
}
}
#[must_use]
pub const fn as_float(&self) -> Option<Float> {
if let Value::Float(v) = self {
Some(*v)
} else {
None
}
}
#[must_use]
pub fn as_bytes(&self) -> Option<&[u8]> {
if let Value::Bytes(v) = self {
Some(v)
} else {
None
}
}
#[must_use]
pub fn as_string(&self) -> Option<&str> {
if let Value::String(v) = self {
Some(v)
} else {
None
}
}
#[must_use]
pub const fn as_array(&self) -> Option<&VecDeque<Value<'a>>> {
if let Value::Array(v) = self {
Some(v)
} else {
None
}
}
#[must_use]
pub const fn as_map(&self) -> Option<&VecDeque<(Value<'a>, Value<'a>)>> {
if let Value::Map(v) = self {
Some(v)
} else {
None
}
}
#[must_use]
pub fn into_values(self) -> Iter<Value<'static>> {
match self.into_owned().0 {
Value::Array(arr) => Iter::new(arr.into_iter()),
Value::Map(map) => Iter::new(map.into_iter().map(|(_key, value)| value)),
_ => Iter::new([].into_iter()),
}
}
}
impl OwnedValue {
#[must_use]
pub fn new(value: Value<'_>) -> Self {
value.into_owned()
}
#[must_use]
pub fn into_inner(self) -> Value<'static> {
self.0
}
}
impl Deref for OwnedValue {
type Target = Value<'static>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for OwnedValue {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<'a> ::core::fmt::Display for Value<'a> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
Value::Null => f.write_str("null"),
Value::Bool(b) if *b => f.write_str("true"),
Value::Bool(_) => f.write_str("false"),
Value::Integer(int) => ::core::fmt::Display::fmt(int, f),
Value::Float(float) => ::core::fmt::Display::fmt(float, f),
Value::Bytes(bytes) => {
f.write_str("0x")?;
for (i, byte) in bytes.iter().enumerate() {
if i > 0 && i % 4 == 0 {
f.write_char('_')?;
}
write!(f, "{byte:02X}")?;
}
Ok(())
}
Value::String(s) => f.write_str(s),
Value::Array(arr) => {
f.write_char('[')?;
for (i, value) in arr.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
::core::fmt::Display::fmt(value, f)?;
}
f.write_char(']')
}
Value::Map(map) => {
f.write_char('{')?;
for (i, (key, value)) in map.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
::core::fmt::Display::fmt(key, f)?;
f.write_str(": ")?;
::core::fmt::Display::fmt(value, f)?;
}
f.write_char('}')
}
}
}
}
impl ::core::fmt::Display for Integer {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
Integer::Unsigned(int) => ::core::fmt::Display::fmt(int, f),
Integer::Signed(int) => ::core::fmt::Display::fmt(int, f),
}
}
}
impl ::core::fmt::Display for Float {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
match self {
Float::F32(float) => ::core::fmt::Display::fmt(float, f),
Float::F64(float) => ::core::fmt::Display::fmt(float, f),
}
}
}
impl<'a> Serialize for Value<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ::serde::Serializer,
{
match self {
Value::Null => serializer.serialize_none(),
Value::Bool(b) => serializer.serialize_bool(*b),
Value::Integer(Integer::Unsigned(int)) => serializer.serialize_u128(*int),
Value::Integer(Integer::Signed(int)) => serializer.serialize_i128(*int),
Value::Float(Float::F32(float)) => serializer.serialize_f32(*float),
Value::Float(Float::F64(float)) => serializer.serialize_f64(*float),
Value::Bytes(bytes) => serializer.serialize_bytes(bytes),
Value::String(s) => serializer.serialize_str(s),
Value::Array(arr) => {
use ::serde::ser::SerializeSeq;
let mut ser = serializer.serialize_seq(Some(arr.len()))?;
for value in arr {
ser.serialize_element(value)?;
}
ser.end()
}
Value::Map(map) => {
use ::serde::ser::SerializeMap;
let mut ser = serializer.serialize_map(Some(map.len()))?;
for (key, value) in map {
ser.serialize_entry(key, value)?;
}
ser.end()
}
}
}
}
impl<'de> Deserialize<'de> for Value<'de> {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor::default())
}
}
impl<'de> Deserialize<'de> for OwnedValue {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(ValueVisitor::default()).map(Value::into_owned)
}
}
#[derive(Debug, Clone, Copy, Default)]
struct ValueVisitor<'a>(PhantomData<Value<'a>>);
impl<'de> ::serde::de::Visitor<'de> for ValueVisitor<'de> {
type Value = Value<'de>;
#[inline]
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("any value")
}
#[inline]
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bool(v))
}
#[inline]
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_i128(i128::from(v))
}
#[inline]
fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Integer(Integer::Signed(v)))
}
#[inline]
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_u128(u128::from(v))
}
#[inline]
fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Integer(Integer::Unsigned(v)))
}
#[inline]
fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Float(Float::F32(v)))
}
#[inline]
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Float(Float::F64(v)))
}
#[inline]
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::String(Cow::Owned(v.to_owned())))
}
#[inline]
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::String(Cow::Borrowed(v)))
}
#[inline]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::String(Cow::Owned(v)))
}
#[inline]
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bytes(Cow::Owned(v.to_vec())))
}
#[inline]
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bytes(Cow::Borrowed(v)))
}
#[inline]
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Bytes(Cow::Owned(v)))
}
#[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Null)
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Null)
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let mut arr = seq.size_hint().map_or_else(VecDeque::new, VecDeque::with_capacity);
while let Some(value) = seq.next_element()? {
arr.push_back(value);
}
Ok(Value::Array(arr))
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let mut entries = map.size_hint().map_or_else(VecDeque::new, VecDeque::with_capacity);
while let Some((key, value)) = map.next_entry()? {
entries.push_back((key, value));
}
Ok(Value::Map(entries))
}
}
impl<'a> PartialEq for Value<'a> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Null, Self::Null) => true,
(Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
(Self::Integer(l0), Self::Integer(r0)) => l0 == r0,
(Self::Float(l0), Self::Float(r0)) => l0 == r0,
(Self::Bytes(l0), Self::Bytes(r0)) => l0 == r0,
(Self::String(l0), Self::String(r0)) => l0 == r0,
(Self::Array(l0), Self::Array(r0)) => l0 == r0,
(Self::Map(l0), Self::Map(r0)) => l0 == r0,
_ => false,
}
}
}
impl<'a> PartialEq<bool> for Value<'a> {
fn eq(&self, other: &bool) -> bool {
match self {
Value::Bool(b) => b == other,
_ => false,
}
}
}
impl<'a> PartialEq<u128> for Value<'a> {
fn eq(&self, other: &u128) -> bool {
match self {
Value::Integer(Integer::Unsigned(int)) => int == other,
_ => false,
}
}
}
impl<'a> PartialEq<i128> for Value<'a> {
fn eq(&self, other: &i128) -> bool {
match self {
Value::Integer(Integer::Signed(int)) => int == other,
_ => false,
}
}
}
impl<'a> PartialEq<f32> for Value<'a> {
fn eq(&self, other: &f32) -> bool {
match self {
Value::Float(Float::F32(float)) => float == other,
Value::Float(Float::F64(float)) => *float == f64::from(*other),
_ => false,
}
}
}
impl<'a> PartialEq<f64> for Value<'a> {
fn eq(&self, other: &f64) -> bool {
match self {
Value::Float(Float::F32(float)) => f64::from(*float) == *other,
Value::Float(Float::F64(float)) => float == other,
_ => false,
}
}
}
impl<'a> PartialEq<[u8]> for Value<'a> {
fn eq(&self, other: &[u8]) -> bool {
match self {
Value::Bytes(bytes) => bytes.as_ref() == other,
_ => false,
}
}
}
impl<'a> PartialEq<str> for Value<'a> {
fn eq(&self, other: &str) -> bool {
match self {
Value::String(s) => s == other,
_ => false,
}
}
}
impl<'a> From<Option<Value<'a>>> for Value<'a> {
#[inline]
fn from(value: Option<Value<'a>>) -> Self {
value.unwrap_or_else(|| Value::Null)
}
}
impl<'a> From<()> for Value<'a> {
#[inline]
fn from(_: ()) -> Self {
Value::Null
}
}
impl<'a> From<bool> for Value<'a> {
#[inline]
fn from(value: bool) -> Self {
Value::Bool(value)
}
}
impl<'a> From<u8> for Value<'a> {
#[inline]
fn from(value: u8) -> Self {
Value::Integer(Integer::Unsigned(u128::from(value)))
}
}
impl<'a> From<i8> for Value<'a> {
#[inline]
fn from(value: i8) -> Self {
Value::Integer(Integer::Signed(i128::from(value)))
}
}
impl<'a> From<u16> for Value<'a> {
#[inline]
fn from(value: u16) -> Self {
Value::Integer(Integer::Unsigned(u128::from(value)))
}
}
impl<'a> From<i16> for Value<'a> {
#[inline]
fn from(value: i16) -> Self {
Value::Integer(Integer::Signed(i128::from(value)))
}
}
impl<'a> From<u32> for Value<'a> {
#[inline]
fn from(value: u32) -> Self {
Value::Integer(Integer::Unsigned(u128::from(value)))
}
}
impl<'a> From<i32> for Value<'a> {
#[inline]
fn from(value: i32) -> Self {
Value::Integer(Integer::Signed(i128::from(value)))
}
}
impl<'a> From<u64> for Value<'a> {
#[inline]
fn from(value: u64) -> Self {
Value::Integer(Integer::Unsigned(u128::from(value)))
}
}
impl<'a> From<i64> for Value<'a> {
#[inline]
fn from(value: i64) -> Self {
Value::Integer(Integer::Signed(i128::from(value)))
}
}
impl<'a> From<usize> for Value<'a> {
#[inline]
fn from(value: usize) -> Self {
Value::Integer(Integer::Unsigned(value as u128))
}
}
impl<'a> From<isize> for Value<'a> {
#[inline]
fn from(value: isize) -> Self {
Value::Integer(Integer::Signed(value as i128))
}
}
impl<'a> From<u128> for Value<'a> {
#[inline]
fn from(value: u128) -> Self {
Value::Integer(Integer::Unsigned(value))
}
}
impl<'a> From<i128> for Value<'a> {
#[inline]
fn from(value: i128) -> Self {
Value::Integer(Integer::Signed(value))
}
}
impl<'a> From<f32> for Value<'a> {
#[inline]
fn from(value: f32) -> Self {
Value::Float(Float::F32(value))
}
}
impl<'a> From<f64> for Value<'a> {
#[inline]
fn from(value: f64) -> Self {
Value::Float(Float::F64(value))
}
}
impl<'a> From<&'a [u8]> for Value<'a> {
#[inline]
fn from(value: &'a [u8]) -> Self {
Value::Bytes(Cow::Borrowed(value))
}
}
impl<'a> From<Vec<u8>> for Value<'a> {
#[inline]
fn from(value: Vec<u8>) -> Self {
Value::Bytes(Cow::Owned(value))
}
}
impl<'a> From<Cow<'a, [u8]>> for Value<'a> {
#[inline]
fn from(value: Cow<'a, [u8]>) -> Self {
Value::Bytes(value)
}
}
impl<'a> From<&'a str> for Value<'a> {
#[inline]
fn from(value: &'a str) -> Self {
Value::String(Cow::Borrowed(value))
}
}
impl<'a> From<String> for Value<'a> {
#[inline]
fn from(value: String) -> Self {
Value::String(Cow::Owned(value))
}
}
impl<'a> From<Cow<'a, str>> for Value<'a> {
#[inline]
fn from(value: Cow<'a, str>) -> Self {
Value::String(value)
}
}
impl<'a> From<VecDeque<Value<'a>>> for Value<'a> {
#[inline]
fn from(value: VecDeque<Value<'a>>) -> Self {
Value::Array(value)
}
}
impl<'a> From<VecDeque<(Value<'a>, Value<'a>)>> for Value<'a> {
#[inline]
fn from(value: VecDeque<(Value<'a>, Value<'a>)>) -> Self {
Value::Map(value)
}
}
impl<'a, T> FromIterator<T> for Value<'a>
where
T: Into<Value<'a>>,
{
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self::from(iter.into_iter().map(Into::into).collect::<VecDeque<_>>())
}
}
impl<'a, K, V> FromIterator<(K, V)> for Value<'a>
where
K: Into<Value<'a>>,
V: Into<Value<'a>>,
{
#[inline]
fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
Self::from(iter.into_iter().map(|(k, v)| (k.into(), v.into())).collect::<VecDeque<_>>())
}
}
trait AllIteratorTrait<Item>:
Iterator<Item = Item> + ExactSizeIterator + DoubleEndedIterator + ::core::fmt::Debug
{
}
impl<I, T> AllIteratorTrait<T> for I where
I: Iterator<Item = T> + ExactSizeIterator + DoubleEndedIterator + ::core::fmt::Debug
{
}
#[derive(Debug)]
pub struct Iter<T>(Box<dyn AllIteratorTrait<T> + Send + Sync>);
impl<T> Iter<T> {
fn new<I>(iter: I) -> Self
where
I: AllIteratorTrait<T> + Send + Sync + 'static,
{
Self(Box::new(iter))
}
}
impl<T> Iterator for Iter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
fn count(self) -> usize
where
Self: Sized,
{
self.0.count()
}
fn last(self) -> Option<Self::Item>
where
Self: Sized,
{
self.0.last()
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth(n)
}
}
impl<T> ExactSizeIterator for Iter<T> {
fn len(&self) -> usize {
self.0.len()
}
}
impl<T> DoubleEndedIterator for Iter<T> {
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.0.nth_back(n)
}
}
#[cfg(test)]
mod tests;