diff options
Diffstat (limited to 'src/features/impl_serde.rs')
-rw-r--r-- | src/features/impl_serde.rs | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/features/impl_serde.rs b/src/features/impl_serde.rs index c3a44e0..ab0db6c 100644 --- a/src/features/impl_serde.rs +++ b/src/features/impl_serde.rs @@ -727,6 +727,14 @@ mod test_f64 { } #[cfg(test)] +mod test_i16 { + pub const V1: i16 = 1; + pub const V2: i16 = 2; + pub const V3: i16 = 3; + pub const V4: i16 = 4; +} + +#[cfg(test)] mod test_i32 { pub const V1: i32 = 1; pub const V2: i32 = 2; @@ -735,6 +743,22 @@ mod test_i32 { } #[cfg(test)] +mod test_i64 { + pub const V1: i64 = 1; + pub const V2: i64 = 2; + pub const V3: i64 = 3; + pub const V4: i64 = 4; +} + +#[cfg(test)] +mod test_u16 { + pub const V1: u16 = 1; + pub const V2: u16 = 2; + pub const V3: u16 = 3; + pub const V4: u16 = 4; +} + +#[cfg(test)] mod test_u32 { pub const V1: u32 = 1; pub const V2: u32 = 2; @@ -743,6 +767,14 @@ mod test_u32 { } #[cfg(test)] +mod test_u64 { + pub const V1: u64 = 1; + pub const V2: u64 = 2; + pub const V3: u64 = 3; + pub const V4: u64 = 4; +} + +#[cfg(test)] mod test_float { pub const SX0: &str = "[]"; pub const SX1: &str = "[1.0]"; @@ -971,6 +1003,21 @@ mod f64 { ); } +mod i16 { + #[cfg(test)] + use super::test_i16::*; + #[cfg(test)] + use super::test_int::*; + use crate::{I16Vec2, I16Vec3, I16Vec4}; + use core::fmt; + use serde::{ + de::{self, Deserialize, Deserializer, SeqAccess, Visitor}, + ser::{Serialize, SerializeTupleStruct, Serializer}, + }; + + impl_serde_vec_types!(i16, I16Vec2, I16Vec3, I16Vec4); +} + mod i32 { #[cfg(test)] use super::test_i32::*; @@ -986,6 +1033,36 @@ mod i32 { impl_serde_vec_types!(i32, IVec2, IVec3, IVec4); } +mod i64 { + #[cfg(test)] + use super::test_i64::*; + #[cfg(test)] + use super::test_int::*; + use crate::{I64Vec2, I64Vec3, I64Vec4}; + use core::fmt; + use serde::{ + de::{self, Deserialize, Deserializer, SeqAccess, Visitor}, + ser::{Serialize, SerializeTupleStruct, Serializer}, + }; + + impl_serde_vec_types!(i64, I64Vec2, I64Vec3, I64Vec4); +} + +mod u16 { + #[cfg(test)] + use super::test_int::*; + #[cfg(test)] + use super::test_u16::*; + use crate::{U16Vec2, U16Vec3, U16Vec4}; + use core::fmt; + use serde::{ + de::{self, Deserialize, Deserializer, SeqAccess, Visitor}, + ser::{Serialize, SerializeTupleStruct, Serializer}, + }; + + impl_serde_vec_types!(u16, U16Vec2, U16Vec3, U16Vec4); +} + mod u32 { #[cfg(test)] use super::test_int::*; @@ -1000,3 +1077,196 @@ mod u32 { impl_serde_vec_types!(u32, UVec2, UVec3, UVec4); } + +mod u64 { + #[cfg(test)] + use super::test_int::*; + #[cfg(test)] + use super::test_u64::*; + use crate::{U64Vec2, U64Vec3, U64Vec4}; + use core::fmt; + use serde::{ + de::{self, Deserialize, Deserializer, SeqAccess, Visitor}, + ser::{Serialize, SerializeTupleStruct, Serializer}, + }; + + impl_serde_vec_types!(u64, U64Vec2, U64Vec3, U64Vec4); +} + +mod euler { + use crate::EulerRot; + + impl serde::Serialize for EulerRot { + fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { + match *self { + EulerRot::ZYX => { + serde::Serializer::serialize_unit_variant(serializer, "EulerRot", 0u32, "ZYX") + } + EulerRot::ZXY => { + serde::Serializer::serialize_unit_variant(serializer, "EulerRot", 1u32, "ZXY") + } + EulerRot::YXZ => { + serde::Serializer::serialize_unit_variant(serializer, "EulerRot", 2u32, "YXZ") + } + EulerRot::YZX => { + serde::Serializer::serialize_unit_variant(serializer, "EulerRot", 3u32, "YZX") + } + EulerRot::XYZ => { + serde::Serializer::serialize_unit_variant(serializer, "EulerRot", 4u32, "XYZ") + } + EulerRot::XZY => { + serde::Serializer::serialize_unit_variant(serializer, "EulerRot", 5u32, "XZY") + } + } + } + } + + impl<'de> serde::Deserialize<'de> for EulerRot { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: serde::Deserializer<'de>, + { + #[allow(clippy::upper_case_acronyms)] + enum Field { + ZYX, + ZXY, + YXZ, + YZX, + XYZ, + XZY, + } + struct FieldVisitor; + + impl<'de> serde::de::Visitor<'de> for FieldVisitor { + type Value = Field; + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + core::fmt::Formatter::write_str(formatter, "variant identifier") + } + fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + match value { + 0u64 => Ok(Field::ZYX), + 1u64 => Ok(Field::ZXY), + 2u64 => Ok(Field::YXZ), + 3u64 => Ok(Field::YZX), + 4u64 => Ok(Field::XYZ), + 5u64 => Ok(Field::XZY), + _ => Err(serde::de::Error::invalid_value( + serde::de::Unexpected::Unsigned(value), + &"variant index 0 <= i < 6", + )), + } + } + fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + match value { + "ZYX" => Ok(Field::ZYX), + "ZXY" => Ok(Field::ZXY), + "YXZ" => Ok(Field::YXZ), + "YZX" => Ok(Field::YZX), + "XYZ" => Ok(Field::XYZ), + "XZY" => Ok(Field::XZY), + _ => Err(serde::de::Error::unknown_variant(value, VARIANTS)), + } + } + fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E> + where + E: serde::de::Error, + { + match value { + b"ZYX" => Ok(Field::ZYX), + b"ZXY" => Ok(Field::ZXY), + b"YXZ" => Ok(Field::YXZ), + b"YZX" => Ok(Field::YZX), + b"XYZ" => Ok(Field::XYZ), + b"XZY" => Ok(Field::XZY), + _ => { + #[cfg(feature = "std")] + let value = &String::from_utf8_lossy(value); + #[cfg(not(feature = "std"))] + let value = + core::str::from_utf8(value).unwrap_or("\u{fffd}\u{fffd}\u{fffd}"); + Err(serde::de::Error::unknown_variant(value, VARIANTS)) + } + } + } + } + impl<'de> serde::Deserialize<'de> for Field { + #[inline] + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: serde::Deserializer<'de>, + { + serde::Deserializer::deserialize_identifier(deserializer, FieldVisitor) + } + } + struct Visitor<'de> { + marker: core::marker::PhantomData<EulerRot>, + lifetime: core::marker::PhantomData<&'de ()>, + } + impl<'de> serde::de::Visitor<'de> for Visitor<'de> { + type Value = EulerRot; + fn expecting( + &self, + __formatter: &mut core::fmt::Formatter<'_>, + ) -> core::fmt::Result { + core::fmt::Formatter::write_str(__formatter, "enum EulerRot") + } + fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error> + where + A: serde::de::EnumAccess<'de>, + { + match serde::de::EnumAccess::variant(data)? { + (Field::ZYX, variant) => { + serde::de::VariantAccess::unit_variant(variant)?; + Ok(EulerRot::ZYX) + } + (Field::ZXY, variant) => { + serde::de::VariantAccess::unit_variant(variant)?; + Ok(EulerRot::ZXY) + } + (Field::YXZ, variant) => { + serde::de::VariantAccess::unit_variant(variant)?; + Ok(EulerRot::YXZ) + } + (Field::YZX, variant) => { + serde::de::VariantAccess::unit_variant(variant)?; + Ok(EulerRot::YZX) + } + (Field::XYZ, variant) => { + serde::de::VariantAccess::unit_variant(variant)?; + Ok(EulerRot::XYZ) + } + (Field::XZY, variant) => { + serde::de::VariantAccess::unit_variant(variant)?; + Ok(EulerRot::XZY) + } + } + } + } + const VARIANTS: &[&str] = &["ZYX", "ZXY", "YXZ", "YZX", "XYZ", "XZY"]; + serde::Deserializer::deserialize_enum( + deserializer, + "EulerRot", + VARIANTS, + Visitor { + marker: core::marker::PhantomData::<EulerRot>, + lifetime: core::marker::PhantomData, + }, + ) + } + } + + #[test] + fn test_euler_rot_serde() { + let a = EulerRot::XYZ; + let serialized = serde_json::to_string(&a).unwrap(); + assert_eq!("\"XYZ\"", serialized); + let deserialized = serde_json::from_str(&serialized).unwrap(); + assert_eq!(a, deserialized); + } +} |