-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#[serde(skip)] cause struct of array containing different length of field #44
Comments
That's unfortunate, but make sense given how everything is implemented. I could see a couple of options here: document the issue and tell people to use code based on |
I prefer
And I just found we also need to validate the length of each field while deserializing(even without any |
|
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8e82c712efe0e6b74d3f10eebe06db0 // #[derive(StructOfArray)]
// #[soa_derive(PartialEq, Debug, Deserialize)]
struct Foo {
a: f32,
// #[soa_attr(serde(skip))]
b: f32,
c: f32,
}
// generated by #[derive(StructOfArray)]
#[derive(PartialEq, Debug)]
struct FooVec {
a: Vec<f32>,
b: Vec<f32>,
c: Vec<f32>,
}
// generated by #[soa_derive(Deserialize)]
mod __detail_mod_foo {
use super::FooVec;
use serde::de::Error;
use serde::{Deserialize, Deserializer};
// same layout as FooVec
#[derive(Deserialize)]
struct DeserializedFooVec {
a: Vec<f32>,
#[serde(skip)]
b: Vec<f32>,
c: Vec<f32>,
}
impl TryFrom<DeserializedFooVec> for FooVec {
type Error = &'static str;
fn try_from(value: DeserializedFooVec) -> Result<Self, Self::Error> {
let len = value.a.len();
if value.c.len() != value.a.len() {
return Err("c.len() != a.len()");
}
Ok(FooVec {
a: value.a,
b: std::iter::repeat_with(Default::default).take(len).collect(),
c: value.c,
})
}
}
impl<'de> Deserialize<'de> for FooVec {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let deserialized = DeserializedFooVec::deserialize(deserializer)?;
let r: Result<FooVec, _> = deserialized.try_into();
r.map_err(|e| <D as Deserializer>::Error::custom(e))
}
}
}
#[test]
fn foo() {
{
let foo_vec = FooVec {
a: vec![1.0, 2.0, 3.0],
b: vec![0.0, 0.0, 0.0],
c: vec![4.0, 5.0, 6.0],
};
let foo_vec_ser = r#"{"a":[1,2,3],"c":[4,5,6]}"#;
let foo_vec_deser: FooVec = serde_json::from_str(foo_vec_ser).unwrap();
assert_eq!(foo_vec, foo_vec_deser);
}
{
let foo_vec_ser = r#"{"a":[1,2,3],"c":[4,5]}"#;
let foo_vec_deser: Result<FooVec, _> = serde_json::from_str(foo_vec_ser);
assert!(foo_vec_deser.is_err());
}
} |
Sometimes we derive serde's
Serialize/Deserialize
for Struct of Array, by#[soa_derive(Serialize, Deserialize)]
.By feature from #42, we are able to skip some Struct of Array's fields by
#[soa_attr(Vec, serde(skip))]
, for example:Serialize is ok, but deserialize will get a invalid
PointVec
because it contains different length of field.For example:
The text was updated successfully, but these errors were encountered: