Rust - 使用 serde/reqwest “无效类型”反序列化

问题描述

我正在尝试反序列化以下 API 响应(为简单起见,我将只复制数组的两个切片,但实际上它会更大)。为了演示示例,代码过于简单。

API 响应:

[[1609632000000,32185,32968,34873,31975,18908.90248876],[1609545600000,29349.83250154,32183,33292,29000,22012.92431526]]

所以这是一个大数组/向量,由带有六个整数 OR 浮点数的数组/向量组成(它们的位置也会有所不同)。

为此,我正在尝试使用泛型,但似乎我错过了一些东西,因为我无法编译它..

它失败了

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: reqwest::Error { kind: Decode,source: Error("invalid type: integer `1609632000000`,expected struct T",line: 1,column: 15) }'

use blocking::Response;
use serde::{Deserialize,Serialize};
use reqwest::{blocking,Error,StatusCode};

struct allData<T> {
    data: Slice<T>
}

#[derive(Debug,Serialize,Deserialize)]
struct Slice<T>{
    data1: T,data2: T,data3: T,data4: T,data5: T,data6: T,}


fn get_data() -> Option<Slice> /*I kNow the signature is not correct,read until the end for the correct one*/ {
    let url = format!("{}",my_url_string);
    let response: Slice<T> = blocking::get(&url).unwrap().json().unwrap();
    Some(response);


}

fn main() {
   let call_the_api = get_data();
   println!("{:?}",call_the_api);
}

将 Struct 与可以返回“切片”向量的泛型一起使用的正确方法是什么。

即。

Vector{
    Slice {
     data1,data2,data3,data4,data5,data6,},Slice {
      data1,}
}

解决方法

Deserialize 结构上的 Slice 派生不适用于 JSON 数组,而是需要一个带有 data1data2 等字段的 JSON 字典。据推测,您不想为您的类型手动实现 Deserialize 特征,因此您需要一个 Vec<Vec<T>> 来为您的嵌套数组建模:

#[derive(Deserialize)]
#[serde(transparent)]
struct AllData<T>(Vec<Vec<T>>);

此类型将 Vec 中的所有项目限制为 T 类型。这意味着,您不能使用一些 f64 和一些 i64,它要么全部是浮点数,要么全部是整数。为了使这个包装器在浮点数和整数上通用,您可能需要一些枚举:

#[derive(Deserialize)]
// note,this causes deserialization to try the variants top-to-bottom
#[serde(untagged)]
enum FloatOrInt {
    Int(i64),Float(f64),}

使用枚举,不再需要 T 上的类型参数 AllData,你可以去:

#[derive(Deserialize)]
#[serde(transparent)]
struct AllData(Vec<Vec<FloatOrInt>>);

如果您确定内部数组的长度始终为 6,则可以将其替换为数组:[FloatOrInt; 6]

把它放在一起,你会得到这样的东西:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=52bd3ce7779cc9b7b152c681de8681c4