Rust serde 反序列化混合数组 [英] Rust serde deserializing a mixed array

查看:112
本文介绍了Rust serde 反序列化混合数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Rust 中,我从 websocket 接收数据.为简单起见,它看起来像这样:

In Rust i am receiving data from a websocket. For simplicity it looks like this:

 [1, {"a": ["1.2345", 5, "9.8765"]}]

我从 websocket 得到的字符串确实是双引号的浮点值"(因此实际上是字符串)和不带引号的整数.

The string i get from the websocket is indeed double-quoted 'floating point values' (thus in actuality strings), and unquoted integers.

我想将此对象反序列化为一个结构体.但是由于返回数组a"是混合类型,我不能使用类似的东西:

I want to deserialize this object into a struct. But since the return array "a" is of mixed type, I can't use something like:

 struct MyStruct {
    id: i32, 
    a: [f64; 3],
 }

所以我想让我们定义另一个结构:

So I thought let's define another struct:

 struct Ask {
    price: f64,
    whole_lot_volume: i64,
    lot_volume: f64
 }

 struct MyStruct {
    id: i32,
    a: Ask
 }

但是我应该如何为此编写解串器?查看 serde 文档我明白我应该为 Ask 编写一个 Visitor:

But how should I write the deserializer for this? Looking at the serde docs I understand that I should write a Visitor for Ask:

 impl<'de> Visitor<'de> for Ask {
    type Value = ...
 }

那么 Value 类型是什么?

所以我确定我没有正确理解反序列化过程是如何工作的.或者 Websocket 返回一个混合类型的数组只是与 serde 反序列化过程不兼容?

So I'm sure I am not correctly understanding how the deserialization process works. Or is the fact that the Websocket returns an array of mixed types just incompatible with the serde deserialization process?

推荐答案

Serde 可以将类似序列的结构和类似映射的结构反序列化为 Rust 结构.

Serde can deserialize to a Rust struct from sequence-like structures as well as map-like ones.

您的结构几乎是正确的,但您的 JSON 中有一个额外的层次结构.如果您的 JSON 是:

Your structs are almost right, but there is an extra layer of hierarchy in your JSON. If your JSON was:

{
    "id": 1,
    "a": [1.2345, 5, 9.8765]
}

然后这将起作用,使用正确的 serde 注释:

then this will just work, with the right serde annotations:

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,你可以使用额外的结构层来匹配:

If you can't change the JSON, you can use an extra layer of structs to match:

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,
}

很少需要实现自己的Visitorserde 提供的 Deserialize 宏是非常可定制的.但是,如果您想省略额外的结构,则必须这样做.

It is rare that you need to implement your own Visitor; the Deserialize macro provided by serde is quite customisable. However, if you want to omit the extra struct, that's what you'd have to do.

如果某些数字表示为 JSON 字符串,您可能需要做更多工作,但您仍然可以在没有自定义 Visitor 实现的情况下执行此操作.见:

You may need to do more work if some of the numbers are represented as JSON strings, but you can still do that without a custom Visitor implementation. See:

这篇关于Rust serde 反序列化混合数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆