二进制(de)序列化[u8; 128]

Tob*_*ann 11 arrays serialization rust deserialization serde

我有一个struct包含字节数组,我想序列化和反序列化二进制文件.但它仅适用于最多32个元素的数组.

这是我的最小示例代码

main.rs:

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

use bincode::{serialize, deserialize, Infinite};

const BYTECOUNT: usize = 32; // 33 and more does not work, I need 128
type DataArr = [u8; BYTECOUNT];

#[derive(Serialize, Deserialize, Debug)]
struct Entry {
    number: i64,
    data: DataArr
}

fn main() {
    let mut my_entry = Entry { number: 12345, data: [0; BYTECOUNT] };
    my_entry.data[4] = 42;

    // Convert the Entry to binary.
    let serialized: Vec<u8> = serialize(&my_entry, Infinite).unwrap();
    println!("serialized = {:?}", serialized);

    // Convert the binary representation back to an Entry.
    let deserialized: Entry = deserialize(&serialized).unwrap();
    println!("deserialized = {:?}", deserialized);
}
Run Code Online (Sandbox Code Playgroud)

Cargo.toml:

[package]
name = "array_serialization_test"
version = "0.1.0"

[dependencies]
serde = "*"
serde_derive = "*"
bincode = "*"
Run Code Online (Sandbox Code Playgroud)

输出:

serialized = [57, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
deserialized = Entry { number: 12345, data: [0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
Run Code Online (Sandbox Code Playgroud)

如何使其适用于阵列中的128个元素?我array_impls!可以用我的用户代码以某种方式手动扩展吗?

128 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 e 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae 31 af 32 ag 33 ah 34 ai 35 aj 36 ak 37 al 38 am 39 an 40 ao 41 ap 42 aq 43 ar 44 as 45 at 46 au 47 av 48 aw 49 ax 50 ay 51 az 52 ba 53 bb 54 bc 55 bd 56 be 57 bf 58 bg 59 bh 60 bi 61 bj 62 bk 63 bl 64 bm 65 bn 66 bo 67 bp 68 bq 69 br 70 bs 71 bt 72 bu 73 bv 74 bw 75 bx 76 by 77 bz 78 ca 79 cb 80 cc 81 cd 82 ce 83 cf 84 cg 85 ch 86 ci 87 cj 88 ck 89 cl 90 cm 91 cn 92 co 93 cp 94 cq 95 cr 96 cs 97 ct 98 cu 99 cv 100 cw 101 cx 102 cy 103 cz 104 da 105 db 106 dc 107 dd 108 de 109 df 110 dg 111 dh 112 di 113 dj 114 dk 115 dl 116 dm 117 dn 118 do 119 dp 120 dq 121 dr 122 ds 123 dt 124 du 125 dv 126 dw 127 dx)
Run Code Online (Sandbox Code Playgroud)

或者有替代方法吗?

注意:我认为这个问题不同于如何使用serde和bincode将填充超过32字节的C结构映射?因为我实际上需要数组的内容,因为它不仅仅用于填充.另外我想知道我是否可以扩展array_impls!我的代码.

dto*_*nay 9

目前,Serde无法为每个阵列大小提供SerializeDeserialize推动该工作.这对于正在进行的常规仿制药是有效的,并且有望在2018年晚些时候在夜间着陆.

现在,您可以定义自己的"大数组"帮助程序,它可以序列化和反序列化您的包中使用的任何特定大小的数组.您要使用大数组助手的字段需要标记,#[serde(with = "BigArray")]否则Serde将查找不存在SerializeDeserializeimpls.

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate bincode;

mod big_array;
use big_array::BigArray;

const BYTECOUNT: usize = 128;
type DataArr = [u8; BYTECOUNT];

#[derive(Serialize, Deserialize)]
struct Entry {
    number: i64,
    #[serde(with = "BigArray")]
    data: DataArr
}

fn main() {
    let mut my_entry = Entry { number: 12345, data: [0; BYTECOUNT] };
    my_entry.data[4] = 42;

    // Convert the Entry to binary.
    let serialized: Vec<u8> = bincode::serialize(&my_entry).unwrap();
    println!("serialized = {:?}", serialized);

    // Convert the binary representation back to an Entry.
    let deserialized: Entry = bincode::deserialize(&serialized).unwrap();
    println!("deserialized = {} {:?}", deserialized.number, &deserialized.data[..]);
}
Run Code Online (Sandbox Code Playgroud)

大数组助手可以如下定义src/big_array.rs.如果您想拥有它,这可能会成为一个好箱子!

use std::fmt;
use std::marker::PhantomData;
use serde::ser::{Serialize, Serializer, SerializeTuple};
use serde::de::{Deserialize, Deserializer, Visitor, SeqAccess, Error};

pub trait BigArray<'de>: Sized {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer;
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>;
}

macro_rules! big_array {
    ($($len:expr,)+) => {
        $(
            impl<'de, T> BigArray<'de> for [T; $len]
                where T: Default + Copy + Serialize + Deserialize<'de>
            {
                fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
                    where S: Serializer
                {
                    let mut seq = serializer.serialize_tuple(self.len())?;
                    for elem in &self[..] {
                        seq.serialize_element(elem)?;
                    }
                    seq.end()
                }

                fn deserialize<D>(deserializer: D) -> Result<[T; $len], D::Error>
                    where D: Deserializer<'de>
                {
                    struct ArrayVisitor<T> {
                        element: PhantomData<T>,
                    }

                    impl<'de, T> Visitor<'de> for ArrayVisitor<T>
                        where T: Default + Copy + Deserialize<'de>
                    {
                        type Value = [T; $len];

                        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                            formatter.write_str(concat!("an array of length ", $len))
                        }

                        fn visit_seq<A>(self, mut seq: A) -> Result<[T; $len], A::Error>
                            where A: SeqAccess<'de>
                        {
                            let mut arr = [T::default(); $len];
                            for i in 0..$len {
                                arr[i] = seq.next_element()?
                                    .ok_or_else(|| Error::invalid_length(i, &self))?;
                            }
                            Ok(arr)
                        }
                    }

                    let visitor = ArrayVisitor { element: PhantomData };
                    deserializer.deserialize_tuple($len, visitor)
                }
            }
        )+
    }
}

big_array! {
    40, 48, 50, 56, 64, 72, 96, 100, 128, 160, 192, 200, 224, 256, 384, 512,
    768, 1024, 2048, 4096, 8192, 16384, 32768, 65536,
}
Run Code Online (Sandbox Code Playgroud)