【问题标题】:Serializing a sequence in Serde when both sequence length and types must be known?当必须知道序列长度和类型时,在 Serde 中序列化一个序列?
【发布时间】:2019-08-13 08:37:36
【问题描述】:

我正在使用 Rust 中的 Serde 序列化程序,用于类似 JSON 的二进制格式。

它对序列使用不同的二进制编码,具体取决于每个元素是否具有相同的大小,或者它是否是具有混合元素大小的序列。

例如:

  • [1, 2, 3]:使用紧凑编码进行序列化,因为所有元素都序列化为相同的字节长度
  • [1, "two", ["a", 1]]:使用不同的编码进行序列化,因为每个元素都序列化为不同的字节长度

根据我对 Serde 的了解,它一次序列化一个元素,并且在序列序列化开始时仅可选地知道序列长度(通过在 Serializer 上调用 serialize_seq)。

是否有一个很好的模式来处理上述情况,在所有元素都被检查(并序列化以知道它们的字节长度)之前无法序列化序列?它还需要处理嵌套序列,如上例所示。

【问题讨论】:

  • 您可以将所有元素存储在您的SerializeSeq 实例中,直到调用end,您将在其中进行实际的序列化。

标签: rust serde


【解决方案1】:

使用来自mcarton 的关于在序列序列化程序中存储元素的建议解决了。

这会将每个序列化的字节序列存储在Vec 中(即作为Vec<Vec<u8>>),并在序列化为output 之前检查所有项的长度是否相等。

这看起来像:

/// Main top level serializer.
pub struct Serializer {
    output: Vec<u8>
}

impl<'a> ser::Serializer for &'a mut Serializer {
    // ... skipped ...

    type SerializeSeq = ArraySerializer<'a>;

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
        let array_ser = ArraySerializer {
            items: Vec::new(),
            output: &mut self.output,
        };
        Ok(array_ser)
    }

    // ... skipped ...
}


pub struct ArraySerializer<'a> {
    /// Temporary storage for individual serialized array elements.
    items: Vec<Vec<u8>>,

    /// Storage for final serialized output of header plus all elements. This is
    /// typically a reference to the full output buffer being serialized into.
    output: &'a mut Vec<u8>,
}

impl <'a> ser::SerializeSeq for ArraySerializer<'a> {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, value: &T) -> Result<Self::Ok> where
        T: ?Sized + Serialize {
        // default serializer used for serializing array elements
        let mut serializer = Serializer::default();

        // serialize individual item and add to `items`
        value.serialize(&mut serializer)?;
        self.items.push(serializer.output);
        Ok(())
    }

    fn end(self) -> Result<Self::Ok> {
        if self.items.is_empty() {
            self.output.push(EMPTY_ARRAY_HEADER);
            return Ok(());
        }

        let all_elems_same_length = self.items
            .iter()
            .all(|ref v| v.len() == self.items[0].len());
        };

        if all_elems_same_length {
            self.output.push(SAME_LENGTH_HEADER);
            for item in &mut self.items.iter_mut() {
                self.output.append(item);
            }
        } else {
            self.output.push(VARIABLE_LENGTH_HEADER);

            // ... skipped: encode rest of items using more complicated serialization ...
        }

        Ok(())
    }
}

【讨论】:

    猜你喜欢
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 2014-01-04
    • 2021-05-11
    • 1970-01-01
    相关资源
    最近更新 更多