我正在尝试反序列化一些具有重复键的 JSON,并且它们可能有任意数量。JSON 看起来像这样:
...
"abilities": [
{
"ability_id": 5134,
"ability_level": 3
},
{
"ability_id": 5136,
"ability_level": 3
}
],
"abilities": [
{
"ability_id": 7710,
"ability_level": 4
}
]
...
Run Code Online (Sandbox Code Playgroud)
我的 Rust 代码是:
#[derive(Deserialize, Debug)]
pub struct Ancient {
score: usize,
tower_state: usize,
barracks_state: usize,
picks: Option<Vec<HeroId>>,
bans: Option<Vec<HeroId>>,
players: Vec<PlayerDetailed>,
abilities: Option<Vec<Ability>> // has many keys
}
Run Code Online (Sandbox Code Playgroud)
该结构Ancient
是 json 中另一个结构的一部分。
只有最后一个abilities
有很多键,而且数量也是可变的,我已经读过这篇文章,但无法将其更改为我喜欢的(我希望最终用户仍然拥有一个结构)。我什至尝试过,#[serde(flatten)]
但它只是让一切None
。如果可能的话我也想改变它:
#[derive(Deserialize, Debug)]
pub struct Ancient {
score: …
Run Code Online (Sandbox Code Playgroud) 我对 Rust 相当陌生,但希望将它用于一些数字工作,并开始探索ndarray箱。serde::Serialize
然而,这样做时,我在尝试导出包含数组的结构时遇到了一些困难serde::Deserialize
。
特别是,我尝试编译以下代码片段,但这样做时出现错误:
extern crate serde;
use ndarray::{ Array1 };
use serde::{ Serialize, Deserialize };
#[derive(Serialize, Deserialize)]
pub struct Canary {
pub xs: Array1<f64>
}
Run Code Online (Sandbox Code Playgroud)
error[E0277]: the trait bound `ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>: serde::Serialize` is not satisfied
--> src/lib.rs:40:5
|
40 | pub xs: Array1<f64>
| ^^^ the trait `serde::Serialize` is not implemented for `ndarray::ArrayBase<ndarray::OwnedRepr<f64>, ndarray::Dim<[usize; 1]>>`
|
= note: required by `serde::ser::SerializeStruct::serialize_field`
Run Code Online (Sandbox Code Playgroud)
# Cargo.toml
[dependencies]
ndarray = { version = "0.12.1", features = …
Run Code Online (Sandbox Code Playgroud) 包含 Box 作为成员变量的结构:
type Item = dyn Fn() -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
struct Inner {
pub data: Box<Item>,
}
// a function, like the type: Item
fn parse() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
println!("parse called");
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
Inner
现在出现了自定义实现结构体反序列化的问题:
let s = r#"{"data": "parse"}"#;
Run Code Online (Sandbox Code Playgroud)
进入结构体内部:
{
data: Box::new(parse)
}
Run Code Online (Sandbox Code Playgroud)
我知道serde
不要实现 deserialize for ,并且必须手动实现 Deserialize ,这是我的代码,遵循docmentaionBox<T>
给出的示例:
let s = r#"{"data": "parse"}"#;
Run Code Online (Sandbox Code Playgroud)
但是,当我运行这些代码时,出现错误:
{
data: Box::new(parse)
}
Run Code Online (Sandbox Code Playgroud)
粗略地说,我猜问题出在(***) …
我正在尝试将以下 JSON 片段反序列化为Vec
of struct Shape
:
use serde::{Deserialize, Serialize};
use serde_json::{Result, Value};
#[derive(Debug, Serialize, Deserialize)]
struct Shape { // this struct is not working, for display purpose only
shape_type: String,
d0: f64,
d1: f64,
d2: f64, //optional, like the case of "dot"
d3: f64, //optional, like the case of "circle"
}
let json = r#"
{[
["line", 1.0, 1.0, 2.0, 2.0],
["circle", 3.0, 3.0, 1.0],
["dot", 4.0, 4.0]
]}"#;
let data: Vec<Shape> = match serde_json::from_str(json)?;
Run Code Online (Sandbox Code Playgroud)
显然,每种类型都Shape
需要 …
我对 Rust 很陌生,并且有 OOP 背景。所以,也许我误解了一些 Rust 基础知识。
我想用 serde 解析固定的 json 结构。该结构代表不同的消息类型之一。每条消息都有一个数字type
属性来区分它。各个消息类型的确切结构大多不同,但它们也可以是相同的。
{"type": 1, "sender_id": 4, "name": "sender", ...}
{"type": 2, "sender_id": 5, "measurement": 3.1415, ...}
{"type": 3, "sender_id": 6, "measurement": 13.37, ...}
...
Run Code Online (Sandbox Code Playgroud)
首先,我定义了 aenum
来区分消息类型,也struct
为每种类型的消息定义了 a ,而没有存储类型的字段。
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Message {
T1(Type1),
T2(Type2),
T3(Type3),
// ...
}
#[derive(Debug, Serialize, Deserialize)]
struct Type1 {
sender_id: u32,
name: String,
// ...
}
#[derive(Debug, Serialize, Deserialize)]
struct Type2 {
sender_id: u32, …
Run Code Online (Sandbox Code Playgroud) 我有两个结构体,我想将它们序列化/反序列化,并将标签作为"type"
JSON 中的字段,如下所示。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
struct ThingA {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
struct ThingB {
value: usize,
}
Run Code Online (Sandbox Code Playgroud)
这些按预期序列化。例如,
let a = ThingA { value: 0 };
println!("{}", serde_json::to_string(&a)?);
// This yields the expected result:
// {"type":"ThingA","value":0}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试添加枚举来代替结构的联合类型时,我遇到了麻烦。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Thing {
ThingA(ThingA),
ThingB(ThingB),
}
Run Code Online (Sandbox Code Playgroud)
上面的定义对于反序列化 JSON 来说效果很好,但在序列化过程中添加了一个额外的字段。
let json = r#"{"type": "ThingB", "value": 0}"#;
let thing: Thing = serde_json::from_str(json)?;
// Correctly …
Run Code Online (Sandbox Code Playgroud) serde::Deserialize
我正在尝试在一个结构体上实现SourceConfig
,该结构体包装了一个包含 的结构体&'static str
以及它自己的一些数据(游乐场):
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Config {
pub name: &'static str,
}
#[derive(Serialize, Deserialize)]
struct SourceConfig {
config: Config,
id: u32,
}
Run Code Online (Sandbox Code Playgroud)
但这给了我一个终生错误:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements
--> src/lib.rs:10:5
|
10 | config: Config,
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'de` as defined on the impl at 8:21...
--> …
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
struct MyStruct {
a: u32,
b: u32
}
#[derive(Serialize, Deserialize)]
#[serde(rename = "MyStruct")]
struct AlsoMyStruct {
a: u32,
b: u32
}
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以安全地做类似的事情:
let ser = any_encoding::serialize(&MyStruct{a: 33, b: 44}).unwrap();
let deser: AlsoMyStruct = any_encoding::deserialize(&ser).unwrap();
Run Code Online (Sandbox Code Playgroud)
其中any_encoding
是,例如bincode
、json
或任何其他 Serde 支持的编码。在我看来,这应该很好地工作:两个结构具有相同的名称(我明确重命名AlsoMyStruct
为"MyStruct"
)和完全相同的字段:相同的字段名称、相同的字段类型、相同的字段顺序。
但是,我想知道:这真的能保证有效吗?MyStruct
或者 Serde 序列化器/反序列化器是否可能在/的表示中包含一些其他的、极端情况的、可能与平台相关的、不可预见的信息,AlsoMyStruct
这些信息可能会导致两种表示不兼容?
我正在编写一个库来解析 json 数据,如下所示:
{"x": [[1, "a"], [2, "b"]]}
Run Code Online (Sandbox Code Playgroud)
即我有一个带有列表列表的键,其中内部列表可以包含不同的数据类型,但每个内部列表具有相同的类型序列。内部列表的类型序列可以针对不同的 json 模式而改变,但会提前知道。
所需的输出将类似于:(
vec![vec![1,2], vec!["a", "b"]]
数据包装在不同数据类型的适当枚举中)。
我开始实现DeserializeSeed
for Vec<DataTypes>
,下面是一些类似的伪代码。
enum DataTypes {
I32,
I64,
String,
F32,
F64
}
fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
where
S: SeqAccess<'de>,
{
let types: Vec<DataTypes> = self.0.data;
let out: Vec<Vec<...>>;
while let Some(inner_seq: S) = seq.next_element::<S>()? { // <-- this is the line
for (i, type) in types.enumerate() {
match type {
DataTypes::I32 => out[i].push(inner_seq.next_element::<i32>()?),
DataTypes::I64 => out[i].push(inner_seq.next_element::<i64>()?),
...
} …
Run Code Online (Sandbox Code Playgroud) 除了这个之外,还有更好(更精简)的方式来表达我自己:
#[derive(Serialize, Deserialize, Debug, Default]
pub struct PagingObject {
#[serde(skip_serializing_if = "Option::is_none")]
offsetId: Option<String>, // offset expressed as element id (uuid)
#[serde(skip_serializing_if = "Option::is_none")]
offset: Option<i32>, // offset expressed as index (numeric)
#[serde(skip_serializing_if = "Option::is_none")]
total: Option<i32>, // total number of elements
#[serde(skip_serializing_if = "Option::is_none")]
totalPages: Option<i32>, // total number of pages based on limit
#[serde(skip_serializing_if = "Option::is_none")]
previous: Option<String>, // link to previous page
#[serde(skip_serializing_if = "Option::is_none")]
next: Option<String>, // link to next page
#[serde(skip_serializing_if = "Option::is_none")]
limit: Option<i32> …
Run Code Online (Sandbox Code Playgroud)