I am making a struct that have arrays, but some of these arrays can have endianness, so I made a kind of wrapper. The problem is that when deserializing such struct, I get error on the visit_seq, it assumes the size of ˋEndianess<[u8, 8]>ˋ to be an extremely big number and thus tries to read something like 397463876483 bytes from bincode.
What is happening? How can the visit_seq know the size of Endianess<[u8, 8]> so it can read just 8 bytes on bincode?
use serde::{
de::{SeqAccess, Visitor},
Deserialize,
};
pub struct Endianess<const ENDIANESS: char, T>(pub T);
impl<'de, const ENDIANESS: char, const N: usize> Deserialize<'de>
for Endianess<ENDIANESS, [u8; N]>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let e = EndianessVisitor::<ENDIANESS, [u8; N]> {
marker: std::marker::PhantomData,
};
deserializer.deserialize_bytes(e)
}
}
pub struct EndianessVisitor<const ENDIANESS: char, T> {
marker: std::marker::PhantomData<Endianess<ENDIANESS, T>>,
}
impl<'a, const ENDIANESS: char, const N: usize> Visitor<'a>
for EndianessVisitor<ENDIANESS, [u8; N]>
{
type Value = Endianess<ENDIANESS, [u8; N]>;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("an array of 8 bytes")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: serde::de::SeqAccess<'a>,
{
let mut value = [0u8; N];
for (i, item) in value.iter_mut().enumerate().take(N) {
*item = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
}
if ENDIANESS == 'L' {
value.reverse();
}
Ok(Endianess(value))
}
}
struct MyStruct {
something: u8,
array: Endianess<'B', [u8; 8]>,
}
struct MyStructVisitor;
impl<'de> Visitor<'de> for MyStructVisitor {
type Value = MyStruct;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a struct")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let something = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
let array = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
Ok(MyStruct { something, array })
}
}
impl<'de> Deserialize<'de> for MyStruct {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_seq(MyStructVisitor)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deserialize() {
let payload = [0, 175, 60, 67, 1, 0, 75, 18, 0, 0, 0, 7, 9, 0];
let my_struct: MyStruct = bincode::deserialize(payload.as_ref()).unwrap();
}
}
dependencies:
[dependencies]
bincode = {version = "1.3.3"}
serde = {version = "1.0.210", features = ["derive"]}