Rust - 使用 serde/reqwest "Invalid type" 反序列化
Rust - deserialization using serde/reqwest "Invalid type"
我正在尝试反序列化以下 API 响应(为简单起见,我将只复制数组的两个切片,但实际上它会更大)。代码过于简化以演示示例。
API 回复:
[[1609632000000,32185,32968,34873,31975,18908.90248876],[1609545600000,29349.83250154,32183,33292,29000,22012.92431526]]
所以这是一个很大的 array/vector,由 arrays/vectors 和六个整数或浮点数组成(它们的位置也会变化)。
为此,我尝试使用泛型,但似乎我遗漏了一些东西,因为我无法编译它..
失败
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 与泛型一起使用的正确方法是什么 return “Slice”的向量。
即
Vector{
Slice {
data1,
data2,
data3,
data4,
data5,
data6,
},
Slice {
data1,
data2,
data3,
data4,
data5,
data6,
}
}
Slice
结构上 Deserialize
的推导不适用于 JSON 数组,而是需要一个 JSON 字段为 data1
的字典, data2
等等。据推测,您不想为您的类型手动实现 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),
}
有了枚举,AllData
上的类型参数 T
就不再需要了,你可以去:
#[derive(Deserialize)]
#[serde(transparent)]
struct AllData(Vec<Vec<FloatOrInt>>);
如果你确定内部数组的长度总是6,你可以用数组替换它:[FloatOrInt; 6]
.
把它放在一起,你会得到这样的东西:
我正在尝试反序列化以下 API 响应(为简单起见,我将只复制数组的两个切片,但实际上它会更大)。代码过于简化以演示示例。
API 回复:
[[1609632000000,32185,32968,34873,31975,18908.90248876],[1609545600000,29349.83250154,32183,33292,29000,22012.92431526]]
所以这是一个很大的 array/vector,由 arrays/vectors 和六个整数或浮点数组成(它们的位置也会变化)。
为此,我尝试使用泛型,但似乎我遗漏了一些东西,因为我无法编译它..
失败
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 与泛型一起使用的正确方法是什么 return “Slice”的向量。
即
Vector{
Slice {
data1,
data2,
data3,
data4,
data5,
data6,
},
Slice {
data1,
data2,
data3,
data4,
data5,
data6,
}
}
Slice
结构上 Deserialize
的推导不适用于 JSON 数组,而是需要一个 JSON 字段为 data1
的字典, data2
等等。据推测,您不想为您的类型手动实现 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),
}
有了枚举,AllData
上的类型参数 T
就不再需要了,你可以去:
#[derive(Deserialize)]
#[serde(transparent)]
struct AllData(Vec<Vec<FloatOrInt>>);
如果你确定内部数组的长度总是6,你可以用数组替换它:[FloatOrInt; 6]
.
把它放在一起,你会得到这样的东西: