use std::collections::HashMap;
use serde::{
Deserialize,
de::VariantAccess,
ser::{SerializeMap, SerializeSeq},
};
use crate::{Error, error::SpecialType, headers::*};
use serde::Serialize;
#[derive(PartialEq)]
pub enum Value {
Null,
True,
False,
#[cfg(feature = "half")]
BF16(half::bf16),
#[cfg(not(feature = "half"))]
BF16,
#[cfg(feature = "half")]
F16(half::f16),
#[cfg(not(feature = "half"))]
F16,
F32(f32),
F64(f64),
F128,
I8(i8),
I16(i16),
I32(i32),
I64(i64),
I128(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
U128(u128),
String(Vec<u8>),
StringObject(Vec<(Vec<u8>, Value)>),
I8Object(Vec<(i8, Value)>),
I16Object(Vec<(i16, Value)>),
I32Object(Vec<(i32, Value)>),
I64Object(Vec<(i64, Value)>),
I128Object(Vec<(i128, Value)>),
U8Object(Vec<(u8, Value)>),
U16Object(Vec<(u16, Value)>),
U32Object(Vec<(u32, Value)>),
U64Object(Vec<(u64, Value)>),
U128Object(Vec<(u128, Value)>),
#[cfg(feature = "half")]
BF16Array(Vec<half::bf16>),
#[cfg(not(feature = "half"))]
BF16Array,
#[cfg(feature = "half")]
F16Array(Vec<half::f16>),
#[cfg(not(feature = "half"))]
F16Array,
F32Array(Vec<f32>),
F64Array(Vec<f64>),
F128Array,
I8Array(Vec<i8>),
I16Array(Vec<i16>),
I32Array(Vec<i32>),
I64Array(Vec<i64>),
I128Array(Vec<i128>),
U8Array(Vec<u8>),
U16Array(Vec<u16>),
U32Array(Vec<u32>),
U64Array(Vec<u64>),
U128Array(Vec<u128>),
BoolArray(usize, Vec<u8>),
StringArray(Vec<Vec<u8>>),
GenericArray(Vec<Value>),
Delimiter,
Tag(usize, Box<Value>),
Matrix {
layout: MatrixLayout,
extents: Box<Value>,
value: Box<Value>,
},
Complex(ComplexNumber),
Reserved,
}
macro_rules! impl_from_primitive {
( $( $ty:ty => $variant:ident $(| $conv:expr)? ),* $(,)? ) => {
$(
impl From<$ty> for Value {
#[inline]
fn from(value: $ty) -> Self {
$(
let value = $conv(value);
)?
Value::$variant(value)
}
}
)*
}
}
impl_from_primitive! {
i8 => I8,
i16 => I16,
i32 => I32,
i64 => I64,
i128 => I128,
u8 => U8,
u16 => U16,
u32 => U32,
u64 => U64,
u128 => U128,
f32 => F32,
f64 => F64,
String => String | |v: String| v.into_bytes(),
&str => String | |v: &str| v.as_bytes().to_vec(),
}
#[cfg(feature = "half")]
impl_from_primitive! {
half::f16 => F16,
half::bf16 => BF16,
}
macro_rules! impl_from_array {
( $( $ty:ty => $variant:ident $(| $conv:expr)? ),* $(,)? ) => {
$(
impl From<Vec<$ty>> for Value {
#[inline]
fn from(value: Vec<$ty>) -> Self {
$(
let value = $conv(value);
)?
Value::$variant(value)
}
}
)*
}
}
impl_from_array! {
i8 => I8Array,
i16 => I16Array,
i32 => I32Array,
i64 => I64Array,
i128 => I128Array,
u8 => U8Array,
u16 => U16Array,
u32 => U32Array,
u64 => U64Array,
u128 => U128Array,
f32 => F32Array,
f64 => F64Array,
&str => StringArray | |v: Vec<&str>| v.iter().map(|v| v.as_bytes().to_vec()).collect(),
String => StringArray | |v: Vec<String>| v.iter().map(|v| v.bytes().collect()).collect(),
}
#[cfg(feature = "half")]
impl_from_array! {
half::f16 => F16Array,
half::bf16 => BF16Array,
}
macro_rules! impl_from_object {
( $( $key:ty => $variant:ident $(| $conv:expr)? ),* $(,)? ) => {
$(
impl<T: Into<Value>> From<HashMap<$key, T>> for Value {
#[inline]
fn from(value: HashMap<$key, T>) -> Self {
Value::$variant(
value
.into_iter()
.map(|(k, v)| {
$(
let k = $conv(k);
)?
(k, v.into())
})
.collect(),
)
}
}
)*
}
}
impl_from_object! {
i8 => I8Object,
i16 => I16Object,
i32 => I32Object,
i64 => I64Object,
i128 => I128Object,
u8 => U8Object,
u16 => U16Object,
u32 => U32Object,
u64 => U64Object,
u128 => U128Object,
String => StringObject | |k: String| k.into_bytes(),
&str => StringObject | |k: &str| k.as_bytes().to_vec(),
}
impl From<()> for Value {
fn from(_value: ()) -> Self {
Value::Null
}
}
impl<T: Into<Value>> From<Option<T>> for Value {
fn from(value: Option<T>) -> Self {
match value {
Some(v) => v.into(),
None => Value::Null,
}
}
}
impl From<bool> for Value {
fn from(value: bool) -> Self {
if value { Value::True } else { Value::False }
}
}
impl From<Vec<bool>> for Value {
fn from(value: Vec<bool>) -> Self {
Value::BoolArray(
value.len(),
value
.chunks(8)
.map(|v| {
let mut out = 0;
for v in v {
out <<= 1;
if *v {
out |= 1
};
}
out
})
.collect(),
)
}
}
impl std::fmt::Debug for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Null => write!(f, "Null"),
Self::True => write!(f, "True"),
Self::False => write!(f, "False"),
#[cfg(feature = "half")]
Self::BF16(v) => f.debug_tuple("BF16").field(v).finish(),
#[cfg(not(feature = "half"))]
Self::BF16 => write!(f, "BF16"),
#[cfg(feature = "half")]
Self::F16(v) => f.debug_tuple("F16").field(v).finish(),
#[cfg(not(feature = "half"))]
Self::F16 => write!(f, "F16"),
Self::F32(v) => f.debug_tuple("F32").field(v).finish(),
Self::F64(v) => f.debug_tuple("F64").field(v).finish(),
Self::F128 => write!(f, "F128"),
Self::I8(v) => f.debug_tuple("I8").field(v).finish(),
Self::I16(v) => f.debug_tuple("I16").field(v).finish(),
Self::I32(v) => f.debug_tuple("I32").field(v).finish(),
Self::I64(v) => f.debug_tuple("I64").field(v).finish(),
Self::I128(v) => f.debug_tuple("I128").field(v).finish(),
Self::U8(v) => f.debug_tuple("U8").field(v).finish(),
Self::U16(v) => f.debug_tuple("U16").field(v).finish(),
Self::U32(v) => f.debug_tuple("U32").field(v).finish(),
Self::U64(v) => f.debug_tuple("U64").field(v).finish(),
Self::U128(v) => f.debug_tuple("U128").field(v).finish(),
Self::String(v) => f
.debug_tuple("String")
.field(&unsafe { std::str::from_utf8_unchecked(v) })
.finish(),
Self::StringObject(v) => {
write!(f, "StringObject ")?;
f.debug_map()
.entries(
v.iter()
.map(|(k, v)| (unsafe { std::str::from_utf8_unchecked(k) }, v)),
)
.finish()
}
Self::I8Object(v) => {
write!(f, "I8Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::I16Object(v) => {
write!(f, "I16Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::I32Object(v) => {
write!(f, "I32Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::I64Object(v) => {
write!(f, "I64Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::I128Object(v) => {
write!(f, "I128Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::U8Object(v) => {
write!(f, "U8Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::U16Object(v) => {
write!(f, "U16Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::U32Object(v) => {
write!(f, "U32Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::U64Object(v) => {
write!(f, "U64Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
Self::U128Object(v) => {
write!(f, "U128Object ")?;
f.debug_map()
.entries(v.iter().map(|(k, v)| (k, v)))
.finish()
}
#[cfg(feature = "half")]
Self::F16Array(v) => f.debug_tuple("F16Array").field(v).finish(),
#[cfg(not(feature = "half"))]
Self::F16Array => write!(f, "F16Array"),
#[cfg(feature = "half")]
Self::BF16Array(v) => f.debug_tuple("BF16Array").field(v).finish(),
#[cfg(not(feature = "half"))]
Self::BF16Array => write!(f, "BF16Array"),
Self::F32Array(v) => f.debug_tuple("F32Array").field(v).finish(),
Self::F64Array(v) => f.debug_tuple("F64Array").field(v).finish(),
Self::F128Array => write!(f, "F128Array"),
Self::I8Array(v) => f.debug_tuple("I8Array").field(v).finish(),
Self::I16Array(v) => f.debug_tuple("I16Array").field(v).finish(),
Self::I32Array(v) => f.debug_tuple("I32Array").field(v).finish(),
Self::I64Array(v) => f.debug_tuple("I64Array").field(v).finish(),
Self::I128Array(v) => f.debug_tuple("I128Array").field(v).finish(),
Self::U8Array(v) => f.debug_tuple("U8Array").field(v).finish(),
Self::U16Array(v) => f.debug_tuple("U16Array").field(v).finish(),
Self::U32Array(v) => f.debug_tuple("U32Array").field(v).finish(),
Self::U64Array(v) => f.debug_tuple("U64Array").field(v).finish(),
Self::U128Array(v) => f.debug_tuple("U128Array").field(v).finish(),
Self::BoolArray(len, v) => f
.debug_tuple("BoolArray")
.field(
&v.iter()
.flat_map(|v| {
let mut out = [false; 8];
for (shift, item) in out.iter_mut().enumerate() {
*item = v >> shift & 1 == 1;
}
out
})
.take(*len)
.collect::<Vec<_>>(),
)
.finish(),
Self::StringArray(v) => f
.debug_tuple("StringArray")
.field(
&v.iter()
.map(|v| unsafe { std::str::from_utf8_unchecked(v) })
.collect::<Vec<_>>(),
)
.finish(),
Self::GenericArray(v) => f.debug_tuple("GenericArray").field(v).finish(),
Self::Delimiter => write!(f, "Delimiter"),
Self::Tag(i, v) => f.debug_tuple("Tag").field(i).field(v).finish(),
Self::Matrix {
layout,
extents,
value,
} => f
.debug_struct("Matrix")
.field("layout", layout)
.field("extents", extents)
.field("value", value)
.finish(),
Self::Complex(c) => f.debug_tuple("Complex").field(c).finish(),
Self::Reserved => write!(f, "Reserved"),
}
}
}
#[derive(Debug, PartialEq, Eq, Serialize)]
pub enum MatrixLayout {
#[serde(rename = "layout_left")]
Left,
#[serde(rename = "layout_right")]
Right,
}
#[derive(Debug, PartialEq)]
pub enum ComplexNumber {
Single((Box<Value>, Box<Value>)),
Array(Vec<(Box<Value>, Box<Value>)>),
}
impl Value {
pub fn header(&self) -> u8 {
match self {
Self::Null => NULL,
Self::True => TRUE,
Self::False => FALSE,
Self::BF16 { .. } => BF16,
Self::F16 { .. } => F16,
Self::F32(..) => F32,
Self::F64(..) => F64,
Self::F128 => F128,
Self::I8(..) => I8,
Self::I16(..) => I16,
Self::I32(..) => I32,
Self::I64(..) => I64,
Self::I128(..) => I128,
Self::U8(..) => U8,
Self::U16(..) => U16,
Self::U32(..) => U32,
Self::U64(..) => U64,
Self::U128(..) => U128,
Self::String(..) => STRING,
Self::StringObject(..) => STRING_OBJECT,
Self::I8Object(..) => I8_OBJECT,
Self::I16Object(..) => I16_OBJECT,
Self::I32Object(..) => I32_OBJECT,
Self::I64Object(..) => I64_OBJECT,
Self::I128Object(..) => I128_OBJECT,
Self::U8Object(..) => U8_OBJECT,
Self::U16Object(..) => U16_OBJECT,
Self::U32Object(..) => U32_OBJECT,
Self::U64Object(..) => U64_OBJECT,
Self::U128Object(..) => U128_OBJECT,
Self::BF16Array { .. } => BF16_ARRAY,
Self::F16Array { .. } => F16_ARRAY,
Self::F32Array(..) => F32_ARRAY,
Self::F64Array(..) => F64_ARRAY,
Self::F128Array => F128_ARRAY,
Self::I8Array(..) => I8_ARRAY,
Self::I16Array(..) => I16_ARRAY,
Self::I32Array(..) => I32_ARRAY,
Self::I64Array(..) => I64_ARRAY,
Self::I128Array(..) => I128_ARRAY,
Self::U8Array(..) => U8_ARRAY,
Self::U16Array(..) => U16_ARRAY,
Self::U32Array(..) => U32_ARRAY,
Self::U64Array(..) => U64_ARRAY,
Self::U128Array(..) => U128_ARRAY,
Self::BoolArray(..) => BOOL_ARRAY,
Self::StringArray(..) => STRING_ARRAY,
Self::GenericArray(..) => GENERIC_ARRAY,
Self::Delimiter => DELIMITER,
Self::Tag(..) => TAG,
Self::Matrix { .. } => MATRIX,
Self::Complex(..) => COMPLEX,
Self::Reserved => RESERVED,
}
}
}
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", header_name(self.header()))
}
}
impl Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
fn serialize_map<S: serde::Serializer, K: Serialize, V: Serialize>(
s: S,
map: &[(K, V)],
) -> Result<S::Ok, S::Error> {
let mut m = s.serialize_map(Some(map.len()))?;
for (k, v) in map {
m.serialize_entry(k, v)?;
}
m.end()
}
fn serialize_seq<S: serde::Serializer, T: Serialize>(
s: S,
seq: &[T],
) -> Result<S::Ok, S::Error> {
let mut s = s.serialize_seq(Some(seq.len()))?;
for v in seq {
s.serialize_element(v)?;
}
s.end()
}
match self {
Self::Null => serializer.serialize_unit(),
Self::True => serializer.serialize_bool(true),
Self::False => serializer.serialize_bool(false),
#[cfg(feature = "half")]
Self::F16(v) => serializer.serialize_f32(v.to_f32()),
#[cfg(not(feature = "half"))]
Self::F16 => Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::HalfFloat,
))),
#[cfg(feature = "half")]
Self::BF16(v) => serializer.serialize_f32(v.to_f32()),
#[cfg(not(feature = "half"))]
Self::BF16 => Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::BrainFloat,
))),
Self::F32(v) => serializer.serialize_f32(*v),
Self::F64(v) => serializer.serialize_f64(*v),
Self::F128 => Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::F128,
))),
Self::I8(v) => serializer.serialize_i8(*v),
Self::I16(v) => serializer.serialize_i16(*v),
Self::I32(v) => serializer.serialize_i32(*v),
Self::I64(v) => serializer.serialize_i64(*v),
Self::I128(v) => serializer.serialize_i128(*v),
Self::U8(v) => serializer.serialize_u8(*v),
Self::U16(v) => serializer.serialize_u16(*v),
Self::U32(v) => serializer.serialize_u32(*v),
Self::U64(v) => serializer.serialize_u64(*v),
Self::U128(v) => serializer.serialize_u128(*v),
Self::String(v) => {
serializer.serialize_str(std::str::from_utf8(v).map_err(serde::ser::Error::custom)?)
}
Self::StringObject(v) => serialize_map(serializer, v),
Self::I8Object(v) => serialize_map(serializer, v),
Self::I16Object(v) => serialize_map(serializer, v),
Self::I32Object(v) => serialize_map(serializer, v),
Self::I64Object(v) => serialize_map(serializer, v),
Self::I128Object(v) => serialize_map(serializer, v),
Self::U8Object(v) => serialize_map(serializer, v),
Self::U16Object(v) => serialize_map(serializer, v),
Self::U32Object(v) => serialize_map(serializer, v),
Self::U64Object(v) => serialize_map(serializer, v),
Self::U128Object(v) => serialize_map(serializer, v),
#[cfg(feature = "half")]
Self::F16Array(v) => serialize_seq(
serializer,
&v.iter().copied().map(half::f16::to_f32).collect::<Vec<_>>(),
),
#[cfg(not(feature = "half"))]
Self::F16Array => Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::HalfFloat,
))),
#[cfg(feature = "half")]
Self::BF16Array(v) => serialize_seq(
serializer,
&v.iter()
.copied()
.map(half::bf16::to_f32)
.collect::<Vec<_>>(),
),
#[cfg(not(feature = "half"))]
Self::BF16Array => Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::BrainFloat,
))),
Self::F32Array(v) => serialize_seq(serializer, v),
Self::F64Array(v) => serialize_seq(serializer, v),
Self::F128Array => Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::F128,
))),
Self::I8Array(v) => serialize_seq(serializer, v),
Self::I16Array(v) => serialize_seq(serializer, v),
Self::I32Array(v) => serialize_seq(serializer, v),
Self::I64Array(v) => serialize_seq(serializer, v),
Self::I128Array(v) => serialize_seq(serializer, v),
Self::U8Array(v) => serialize_seq(serializer, v),
Self::U16Array(v) => serialize_seq(serializer, v),
Self::U32Array(v) => serialize_seq(serializer, v),
Self::U64Array(v) => serialize_seq(serializer, v),
Self::U128Array(v) => serialize_seq(serializer, v),
Self::BoolArray(len, v) => serialize_seq(
serializer,
&v.iter()
.flat_map(|v| {
let mut out = [false; 8];
for (shift, item) in out.iter_mut().enumerate() {
*item = v >> shift & 1 == 1;
}
out
})
.take(*len)
.collect::<Vec<_>>(),
),
Self::StringArray(v) => serialize_seq(
serializer,
&v.iter()
.map(|v| std::str::from_utf8(v).map_err(serde::ser::Error::custom))
.collect::<Result<Vec<_>, _>>()?,
),
Self::GenericArray(v) => serialize_seq(serializer, v),
Self::Tag(i, v) => serializer.serialize_newtype_variant("", *i as u32, "", v),
Self::Delimiter => Err(serde::ser::Error::custom(
"Delimiter can't be serialized with serde",
)),
Self::Matrix {
layout,
extents,
value,
} => {
let mut map = serializer.serialize_map(Some(3))?;
map.serialize_entry("layout", layout)?;
if matches!(
**extents,
Self::I8Array(_)
| Self::I16Array(_)
| Self::I32Array(_)
| Self::I64Array(_)
| Self::I128Array(_)
| Self::U8Array(_)
| Self::U16Array(_)
| Self::U32Array(_)
| Self::U64Array(_)
| Self::U128Array(_)
) {
map.serialize_entry("extents", extents)?;
} else {
return Err(serde::ser::Error::custom(
"Matrix extents must be a typed array of integers",
));
}
match **value {
Self::F32Array(..)
| Self::F64Array(..)
| Self::I8Array(..)
| Self::I16Array(..)
| Self::I32Array(..)
| Self::I64Array(..)
| Self::I128Array(..)
| Self::U8Array(..)
| Self::U16Array(..)
| Self::U32Array(..)
| Self::U64Array(..)
| Self::U128Array(..) => {
map.serialize_entry("value", value)?;
}
#[cfg(feature = "half")]
Self::BF16Array(..) => {
map.serialize_entry("value", value)?;
}
#[cfg(not(feature = "half"))]
Self::BF16Array => {
return Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::BrainFloat,
)));
}
#[cfg(feature = "half")]
Self::F16Array(..) => {
map.serialize_entry("value", value)?;
}
#[cfg(not(feature = "half"))]
Self::F16Array => {
return Err(serde::ser::Error::custom(Error::UnsupportedDataType(
SpecialType::HalfFloat,
)));
}
Self::F128Array => {
return Err(serde::ser::Error::custom(
crate::Error::UnsupportedDataType(crate::error::SpecialType::F128),
));
}
_ => {
return Err(serde::ser::Error::custom(
"Matrix value must be a typed array of numbers",
));
}
}
map.end()
}
Self::Complex(c) => match c {
ComplexNumber::Single((re, im)) => match (re.as_ref(), im.as_ref()) {
(Value::F32(_), Value::F32(_))
| (Value::F64(_), Value::F64(_))
| (Value::I8(_), Value::I8(_))
| (Value::I16(_), Value::I16(_))
| (Value::I32(_), Value::I32(_))
| (Value::I64(_), Value::I64(_))
| (Value::I128(_), Value::I128(_))
| (Value::U8(_), Value::U8(_))
| (Value::U16(_), Value::U16(_))
| (Value::U32(_), Value::U32(_))
| (Value::U64(_), Value::U64(_))
| (Value::U128(_), Value::U128(_)) => {
let mut seq = serializer.serialize_seq(Some(2))?;
seq.serialize_element(re)?;
seq.serialize_element(im)?;
seq.end()
}
_ => Err(serde::ser::Error::custom(
"Complex number must be a pair of numbers of the same type",
)),
},
ComplexNumber::Array(v) => {
let mut seq = serializer.serialize_seq(Some(v.len()))?;
for (re, im) in v {
match (re.as_ref(), im.as_ref()) {
(Value::F32(_), Value::F32(_))
| (Value::F64(_), Value::F64(_))
| (Value::I8(_), Value::I8(_))
| (Value::I16(_), Value::I16(_))
| (Value::I32(_), Value::I32(_))
| (Value::I64(_), Value::I64(_))
| (Value::I128(_), Value::I128(_))
| (Value::U8(_), Value::U8(_))
| (Value::U16(_), Value::U16(_))
| (Value::U32(_), Value::U32(_))
| (Value::U64(_), Value::U64(_))
| (Value::U128(_), Value::U128(_)) => {
seq.serialize_element(&[re, im])?;
}
_ => {
return Err(serde::ser::Error::custom(
"Complex number must be a pair of numbers of the same type",
));
}
}
}
seq.end()
}
},
Self::Reserved => Err(serde::ser::Error::custom(
"Reserved value can't be serialized with serde",
)),
}
}
}
impl<'de> Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct ValueVisitor;
macro_rules! visit_number {
($fn: ident, $ty:ty, $variant:ident) => {
fn $fn<E>(self, v: $ty) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::$variant(v))
}
};
}
impl<'de> serde::de::Visitor<'de> for ValueVisitor {
type Value = Value;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "a BEVE value")
}
visit_number!(visit_i8, i8, I8);
visit_number!(visit_i16, i16, I16);
visit_number!(visit_i32, i32, I32);
visit_number!(visit_i64, i64, I64);
visit_number!(visit_i128, i128, I128);
visit_number!(visit_u8, u8, U8);
visit_number!(visit_u16, u16, U16);
visit_number!(visit_u32, u32, U32);
visit_number!(visit_u64, u64, U64);
visit_number!(visit_u128, u128, U128);
visit_number!(visit_f32, f32, F32);
visit_number!(visit_f64, f64, F64);
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(v.into())
}
fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
self.visit_str(&v.to_string())
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::String(v.as_bytes().to_vec()))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::String(v.into_bytes()))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::U8Array(v.to_vec()))
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Null)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(Value::Null)
}
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(self)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'de>,
{
let Some(first) = seq.next_element::<Value>()? else {
return Ok(Value::GenericArray(vec![]));
};
let mut kind = ArrayKind::from(&first);
let mut out = vec![first];
while let Some(value) = seq.next_element::<Value>()? {
if ArrayKind::from(&value) != kind {
kind = ArrayKind::Generic;
}
out.push(value);
}
macro_rules! convert_array {
( $( $(#[$meta:meta])* $kind:ident => $array:ident ),* $(,)? | $( $(#[$other_meta:meta])* $other:ident => $other_val:expr ),* $(,)? ) => {
match kind {
$(
$(#[$meta])*
ArrayKind::$kind => Value::$array(
out.into_iter()
.map(|v| match v {
Value::$kind(v) => v,
_ => unreachable!(),
})
.collect(),
),
)*
$(
$(#[$other_meta])*
ArrayKind::$other => $other_val,
)*
}
}
}
Ok(convert_array! {
I8 => I8Array,
I16 => I16Array,
I32 => I32Array,
I64 => I64Array,
I128 => I128Array,
U8 => U8Array,
U16 => U16Array,
U32 => U32Array,
U64 => U64Array,
U128 => U128Array,
#[cfg(feature = "half")]
BF16 => BF16Array,
#[cfg(feature = "half")]
F16 => F16Array,
F32 => F32Array,
F64 => F64Array,
String => StringArray,
|
#[cfg(not(feature = "half"))]
F16 => Value::F16,
#[cfg(not(feature = "half"))]
BF16 => Value::BF16,
F128 => Value::F128Array,
Boolean => Value::BoolArray(
out.len(),
out.chunks(8)
.map(|v| {
let mut out = 0;
for v in v.iter().rev() {
out <<= 1;
if let Value::True = *v {
out |= 1
};
}
out
})
.collect(),
),
Generic => Value::GenericArray(out),
Complex => unreachable!(),
})
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: serde::de::MapAccess<'de>,
{
let Some(first) = map.next_entry::<Value, Value>()? else {
return Ok(Value::StringObject(vec![]));
};
let kind = ObjectKind::try_from(&first.0).map_err(serde::de::Error::custom)?;
let mut out = vec![first];
while let Some(entry) = map.next_entry::<Value, Value>()? {
let found = ObjectKind::try_from(&entry.0).map_err(serde::de::Error::custom)?;
if found != kind {
return Err(serde::de::Error::custom(crate::Error::MismatchedKeyType {
expected: kind,
found,
}));
}
out.push(entry);
}
macro_rules! convert_object {
( $( $(#[$meta:meta])* $kind:ident => $object:ident ),* $(,)? ) => {
match kind {
$(
$(#[$meta])*
ObjectKind::$kind => Value::$object(
out.into_iter()
.map(|v| match v {
(Value::$kind(k), v) => (k, v),
_ => unreachable!(),
})
.collect(),
),
)*
}
}
}
Ok(convert_object! {
I8 => I8Object,
I16 => I16Object,
I32 => I32Object,
I64 => I64Object,
I128 => I128Object,
U8 => U8Object,
U16 => U16Object,
U32 => U32Object,
U64 => U64Object,
U128 => U128Object,
String => StringObject,
})
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: serde::de::EnumAccess<'de>,
{
let (variant, value) = data.variant::<usize>()?;
Ok(Value::Tag(
variant,
Box::new(value.newtype_variant::<Value>()?),
))
}
}
deserializer.deserialize_any(ValueVisitor)
}
}