我想定义一个表示浮点数的struct类型,并且在为其实现serde时,表现的就像是一个浮点数,而不是一个struct。
下面是源码。上半部分是MyFloat
的定义和serde实现。下半部分的main函数是用json和msgpack的测试。
这里为了简单起见,MyFloat内部只是一个f64。但在实际代码中,这个类型的定义更加复杂,所以这里不能直接用serde(transparent)
,而是必须手动实现serde。
use serde::{Serialize, Deserialize, Serializer, Deserializer};
// impl Serialize and Deserialize for MyFloat
#[derive(Debug)]
struct MyFloat {
inner: f64
}
impl Serialize for MyFloat {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
self.inner.serialize(serializer) // <---- dump as float number
}
}
impl<'de> Deserialize<'de> for MyFloat {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
use serde::de::{self, Visitor};
struct MyFloatVistor;
impl<'de> Visitor<'de> for MyFloatVistor {
type Value = MyFloat;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "MyFloat")
}
fn visit_f64<E>(self, f: f64) -> Result<Self::Value, E>
where E: de::Error,
{
Ok(MyFloat { inner: f }) // <----- parse float number
}
}
deserializer.deserialize_str(MyFloatVistor)
}
}
// test using struct Req
#[derive(Serialize, Deserialize, Debug)]
struct Req {
num: MyFloat,
}
fn main() {
let req = Req {
num: MyFloat { inner: 123.456 }
};
// MsgPacker
let ser = rmp_serde::to_vec_named(&req).unwrap();
println!("MsgPacker serialized = {:?}", ser);
let de: Req = rmp_serde::from_slice(&ser).unwrap();
println!("MsgPacker deserialized = {:?}", de); // <==== good
// json
let ser = serde_json::to_string(&req).unwrap();
println!("json serialized = {}", ser);
let de: Req = serde_json::from_str(&ser).unwrap();
println!("json deserialized = {:?}", de); // <==== fail !!!
}
其运行结果如下:
MsgPacker serialized = [129, 163, 110, 117, 109, 203, 64, 94, 221, 47, 26, 159, 190, 119]
MsgPacker deserialized = Req { num: MyFloat { inner: 123.456 } }
json serialized = {"num":123.456}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: floating point `123.456`, expected MyFloat", line: 1, column: 14)', src/main.rs:59:46
可以看到msgpack的ser/de都正常。但json的de就失败了。
我以为msgpack和json是类似的格式,都是自描述的。但是为什么我的这个情况中,msgpack可以,但是json就失败呢?
1
共 3 条评论, 1 页
评论区
写评论因为你用错函数了..
deserialize_f64
确实,是这里写错了。。。。。
改成deserializer.deserialize_f64,就好了。
这里之前是从其他地方copy过来的。漏掉改这里了。
多谢
我不知道你的message pack是怎么解析成功的,但是既然你的visitor只实现了f64的方法,那你也只应该调用deserialize_f64.