Rust serde 反序列化混合数组
Rust serde deserializing a mixed array
在 Rust 中,我从 websocket 接收数据。为简单起见,它看起来像这样:
[1, {"a": ["1.2345", 5, "9.8765"]}]
我从 websocket 获得的字符串确实是双引号 'floating point values'(因此实际上是字符串)和未引号的整数。
我想将这个对象反序列化为一个结构。但是由于 return 数组 "a" 是混合类型,我不能使用类似的东西:
struct MyStruct {
id: i32,
a: [f64; 3],
}
所以我想让我们定义另一个结构:
struct Ask {
price: f64,
whole_lot_volume: i64,
lot_volume: f64
}
struct MyStruct {
id: i32,
a: Ask
}
但是我应该如何为此编写反序列化器呢?查看 serde
文档,我明白我应该为 Ask
:
写一个 Visitor
impl<'de> Visitor<'de> for Ask {
type Value = ...
}
但是 Value
类型是什么?
所以我确定我没有正确理解反序列化过程的工作原理。还是 Websocket return 是一个混合类型数组与 serde 反序列化过程不兼容?
Serde 可以从类序列结构和类映射结构反序列化为 Rust 结构。
您的结构几乎是正确的,但是您的 JSON 中多了一层层次结构。如果您的 JSON 是:
{
"id": 1,
"a": [1.2345, 5, 9.8765]
}
然后这将正常工作,带有正确的 serde
注释:
use serde::{Serialize, Deserialize};
#[derive(Deserialize)]
struct Ask {
price: f64,
whole_lot_volume: i64,
lot_volume: f64,
}
#[derive(Deserialize)]
struct MyStruct {
id: i32,
a: Ask,
}
如果无法更改JSON,可以使用额外的结构层来匹配:
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
struct Order {
price: f64,
whole_lot_volume: i64,
lot_volume: f64,
}
#[derive(Debug, Deserialize)]
struct Ask {
a: Order,
}
#[derive(Debug, Deserialize)]
struct MyStruct {
id: i32,
a: Ask,
}
您很少需要实现自己的 Visitor
; serde
提供的 Deserialize
宏非常可定制。但是,如果您想省略额外的结构,那就是您必须做的。
如果某些数字表示为 JSON 字符串,您可能需要做更多的工作,但您仍然可以在没有自定义 Visitor
实现的情况下完成。参见:
- How to transform fields during deserialization using Serde?
- Serde field attributes
在 Rust 中,我从 websocket 接收数据。为简单起见,它看起来像这样:
[1, {"a": ["1.2345", 5, "9.8765"]}]
我从 websocket 获得的字符串确实是双引号 'floating point values'(因此实际上是字符串)和未引号的整数。
我想将这个对象反序列化为一个结构。但是由于 return 数组 "a" 是混合类型,我不能使用类似的东西:
struct MyStruct {
id: i32,
a: [f64; 3],
}
所以我想让我们定义另一个结构:
struct Ask {
price: f64,
whole_lot_volume: i64,
lot_volume: f64
}
struct MyStruct {
id: i32,
a: Ask
}
但是我应该如何为此编写反序列化器呢?查看 serde
文档,我明白我应该为 Ask
:
Visitor
impl<'de> Visitor<'de> for Ask {
type Value = ...
}
但是 Value
类型是什么?
所以我确定我没有正确理解反序列化过程的工作原理。还是 Websocket return 是一个混合类型数组与 serde 反序列化过程不兼容?
Serde 可以从类序列结构和类映射结构反序列化为 Rust 结构。
您的结构几乎是正确的,但是您的 JSON 中多了一层层次结构。如果您的 JSON 是:
{
"id": 1,
"a": [1.2345, 5, 9.8765]
}
然后这将正常工作,带有正确的 serde
注释:
use serde::{Serialize, Deserialize};
#[derive(Deserialize)]
struct Ask {
price: f64,
whole_lot_volume: i64,
lot_volume: f64,
}
#[derive(Deserialize)]
struct MyStruct {
id: i32,
a: Ask,
}
如果无法更改JSON,可以使用额外的结构层来匹配:
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
struct Order {
price: f64,
whole_lot_volume: i64,
lot_volume: f64,
}
#[derive(Debug, Deserialize)]
struct Ask {
a: Order,
}
#[derive(Debug, Deserialize)]
struct MyStruct {
id: i32,
a: Ask,
}
您很少需要实现自己的 Visitor
; serde
提供的 Deserialize
宏非常可定制。但是,如果您想省略额外的结构,那就是您必须做的。
如果某些数字表示为 JSON 字符串,您可能需要做更多的工作,但您仍然可以在没有自定义 Visitor
实现的情况下完成。参见:
- How to transform fields during deserialization using Serde?
- Serde field attributes