尽管 None 包含在 Option 变量中,但在 bincode 反序列化中包含一个 None 将引发错误

Including a None in a bincode deserialization will throw an Error despite being contained in an Option variable

我想编写一个结构,该结构具有与 bincode 之间的相应(反)序列化。作为 MRE,这是结构:

use serde::{Deserialize, Serialize, Deserializer, Serializer};
use serde_with::skip_serializing_none;
use bincode;
use std::net::IpAddr;
use core::str::FromStr;
use core::fmt::Debug;

#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ip_struct {
    pub loc_ip: Option<IpAddr>,
    pub sending_p: Option<u16>,
    pub opt_id: Option<String>,
}

(反)序列化在实现块中看起来像这样:

impl ip_struct {

    // Serialization/deserialization bincode
    pub fn new_from_bincode(bincode_vec: &Vec<u8>) -> ip_struct {
        bincode::deserialize(&bincode_vec).unwrap()
    }
    pub fn to_bincode(&self) -> Vec<u8> {
        bincode::serialize(&self).unwrap()
    }

}

运行一个简单的测试,代码出现panic并抛出错误。

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_from_to_bincode() {
        let test_flow = ip_struct {
            loc_ip: Some(IpAddr::from_str("0.0.0.0").unwrap()),
            sending_p: Some(443),
            opt_id: None,
        };

        let encoded_vec = test_flow.to_bincode();
        let res = ip_struct::new_from_bincode(&encoded_vec);

    }

}

错误为:

called `Result::unwrap()` on an `Err` value: Io(Kind(UnexpectedEof))
thread 'playground::tests::test_from_to_bincode' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Kind(UnexpectedEof))'

在网上没有找到关于错误的信息,但是我不太清楚程序失败的原因。在 ip_struct 中的 opt_id 上删除或设置 Some() 中的字符串不会导致错误,但我的理解是 Option 模块将能够处理 None作为一个值,与将任何值设置为零相反。如何在仍然能够处理 None 值的同时解决此问题?

您不能使用 Bincode 跳过字段。

Bincode 不是 self-describing,所以如果您跳过一个字段,它无法判断它是 None 还是应该继续解析输入的其余部分。

只需删除 #[skip_serializing_none].