Rust 如何使用serde和bincode映射填充超过32字节的C结构?

Rust 如何使用serde和bincode映射填充超过32字节的C结构?,rust,serde,Rust,Serde,我正在使用serde和bincode映射一个二进制结构 #[macro_use] extern crate serde_derive; extern crate serde; extern crate bincode; #[derive(Serialize, Deserialize)] struct Superblock { magic: [u8; 16], //reserved: [u8; 492], crc: u32, } 事情按预期进行,但我无法映射保留字段。显

我正在使用serde和bincode映射一个二进制结构

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;

#[derive(Serialize, Deserialize)]
struct Superblock {
    magic: [u8; 16],
    //reserved: [u8; 492],
    crc: u32,
}
事情按预期进行,但我无法映射保留字段。显然,固定大小的数组只针对最大32字节的大小定义

如何注册自定义大小的数组,以便对填充进行反序列化

serde+bincode是正确的方法吗?
我需要控制endianness(bincode提供),我喜欢声明式风格。

serde_派生支持
[serde(serialize_with=“func”)]
[serde(deserialize_with=“func”)]
[serde(with=“module”)]
,它允许提供自定义序列化/反序列化例程:

#[derive(Serialize, Deserialize)]
struct Superblock {
    magic: [u8; 16],
    #[serde(with="array_492")]   // <--
    reserved: [u8; 492],
    crc: u32,
}

mod array_492 {
    use serde::*;

    pub fn serialize<S, T>(array: &[T; 492], ser: S) -> Result<S::Ok, S::Error> 
        where S: Serializer, T: Serialize
    {
        unimplemented!() // fill in yourself.
    }

    pub fn deserialize<'de, D, T>(de: D) -> Result<[T; 492], D::Error> { 
        where D: Deserializer<'de>, T: Deserialize<'de>
    {
        unimplemented!() // fill in yourself.
    }
}
#[派生(序列化、反序列化)]
结构超块{
魔术:[u8;16],
#[serde(with=“array492”)]//结果
其中S:Serializer,T:Serialize
{
未执行!()//填写您自己。
}

pub fn deserialize,T:deserialize作为一种解决方法,您可以构造一个大小合适的不同对象,并忽略它。例如:

reserved: ([u64; 32], [u64; 29], u32) // 492 bytes
我推荐和作为定制类型

需要注意的是,您根本不关心数据。这意味着没有理由占用内存!我们可以定义一个类型
Reserved
,它将序列化为一组字节,并从字节反序列化,但实际上不需要内存结构中的任何空间

然后,只需填写trait实现:

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;

use std::fmt;
use serde::ser::SerializeTuple;

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Superblock {
    magic: [u8; 16],
    reserved: Reserved,
    crc: u32,
}

#[derive(Debug, PartialEq)]
struct Reserved;
const RESERVED_LENGTH: usize = 492;

impl serde::Serialize for Reserved {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: serde::Serializer
    {
        let mut tuple = serializer.serialize_tuple(RESERVED_LENGTH)?;
        for _ in 0..RESERVED_LENGTH {
            tuple.serialize_element(&0xA0_u8)?; // Just to see it easily in the output
        }
        tuple.end()
    }
}

impl<'de> serde::Deserialize<'de> for Reserved {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: serde::Deserializer<'de>
    {
        struct Visitor;
        impl<'de> serde::de::Visitor<'de> for Visitor {
            type Value = Reserved;

            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "{} bytes", RESERVED_LENGTH)
            }

            fn visit_seq<A>(self, mut tuple: A) -> Result<Self::Value, A::Error>
                where A: serde::de::SeqAccess<'de>,
            {
                for _ in 0..RESERVED_LENGTH {
                    tuple.next_element::<u8>()?;
                }
                Ok(Reserved)
            }
        }

        deserializer.deserialize_tuple(RESERVED_LENGTH, Visitor)
    }
}

fn main() {
    let block = Superblock {
        magic: [
            0x00, 0x01, 0x02, 0x03,
            0x04, 0x05, 0x06, 0x07,
            0x08, 0x09, 0x0a, 0x0b,
            0x0c, 0x0d, 0x0e, 0x0f,
        ],
        reserved: Reserved,
        crc: 0xffffffff,
    };

    let ser = bincode::serialize(&block, bincode::Infinite).expect("Couldn't serialize");
    println!("length: {}", ser.len());
    println!("{:?}", ser);

    let block2: Superblock = bincode::deserialize(&ser).expect("Couldn't deserialize");
    assert_eq!(block, block2);
    println!("{:?}", block2);

    println!("Takes: {} bytes", std::mem::size_of::<Superblock>());
    // prints "Takes: 20 bytes"
}
#[宏使用]
外部板条箱serde_;
外部板条箱;
外部板条箱箱代码;
使用std::fmt;
使用serde::ser::SerializeTuple;
#[派生(调试、序列化、反序列化、PartialEq)]
结构超块{
魔术:[u8;16],
保留的,保留的,
crc:u32,
}
#[派生(调试,部分Q)]
结构保留;
常数保留长度:usize=492;
impl serde::为保留{
fn序列化(&self,序列化程序:S)->结果
其中S:serde::Serializer
{
让mut tuple=serializer.serialize_tuple(保留长度)?;
对于0中的u..保留长度{
tuple.serialize_元素(&0xA0_u8);//只是为了在输出中方便地看到它
}
tuple.end()
}
}
保留的impl{
fn反序列化(反序列化程序:D)->结果
其中D:serde::反序列化器serde::de::Visitor,
{
对于0中的u..保留长度{
tuple.next_元素::()?;
}
Ok(保留)
}
}
反序列化程序。反序列化元组(保留长度,访问者)
}
}
fn main(){
let block=超级块{
魔术:[
0x00,0x01,0x02,0x03,
0x04、0x05、0x06、0x07,
0x08、0x09、0x0a、0x0b、,
0x0c,0x0d,0x0e,0x0f,
],
保留的,保留的,
crc:0xffffffff,
};
让ser=bincode::serialize(&block,bincode::Infinite);
println!(“长度:{}”,ser.len());
println!(“{:?}”,ser);
let block2:Superblock=bincode::反序列化(&ser).expect(“无法反序列化”);
断言(块,块2);
println!(“{:?}”,区块2);
println!((“获取:{}字节”,std::mem::size_of::());
//打印“需要20个字节”
}

我想我会放弃填充,使用字节顺序分别获取CRC。如果你想使用一个固定大小的数组,可能会很有用。它具有允许serde反序列化的
serde
功能。它不是一个固定大小的数组,实现方式略有不同,但内存表示形式完全相同,应该允许所有相同的使用。谢谢!因为这只是填充,所以几乎为空的实现就可以了。谢谢!将长度作为一个通用参数,这可能是bincode中值得添加的一个参数。@Gabriel遗憾的是,类型级别的数字还不存在,所以您必须使用类似的东西,这会增加一点不美观。然而,当他们着陆时,我认为这是一个非常适合bincode的东西!