【发布时间】:2022-08-15 06:05:25
【问题描述】:
我正在使用 serde 反序列化两个结构之一。输入来自 csv 文件。
use std::error::Error;
use std::str::FromStr;
use std::io;
use std::process;
use serde::{Deserialize, Deserializer, Serialize};
#[derive(Deserialize)]
struct A {
value: i8,
}
#[derive(Deserialize)]
struct B {
value: String,
}
#[derive(Deserialize)]
#[serde(untagged)]
enum C {
One(A),
Two(B),
}
fn main() {
let mut rdr = csv::Reader::from_reader(io::stdin());
for result in rdr.deserialize() {
let record: Result<C, csv::Error> = result;
match record {
Ok(value) => {
println!(\"ok\");
}
Err(error) => {
println!(\"Error parsing line: {}\", error);
}
}
}
}
如果我正确理解未标记的枚举,这应该尝试将其解析为 A 结构,所以只是一个 i8,如果失败,尝试将其解析为 B 结构,所以只是一个字符串。
我已经验证我的结构可以自行正确反序列化。
这是我运行的命令:
echo \"value\\nTest\\n1\" | cargo r
这是输出:
Error parsing line: CSV deserialize error: record 1 (line: 2, byte: 6): data did not match any variant of untagged enum C
Error parsing line: CSV deserialize error: record 2 (line: 3, byte: 11): data did not match any variant of untagged enum C
-
如果您将
A和B标记为serde(transparent)是否有效? -
@FilipeRodrigues 确实如此,但是在我的实际代码中,我的结构中有多个字段,如果我正确理解
#[serde(transparent)],则它不适用于这种情况。 -
根本问题是,至少在这种情况下,反序列化程序在反序列化时期望
A(\"value\")或B(1)值,但它发现\"value\",这与任何一种情况都不匹配。这并不特定于未标记的枚举,我相信,标记的枚举也不允许从\"value\"解析A(\"value\"),只能使用serde(transparent)。如果您不能这样标记枚举,您可能需要一些自定义反序列化器来根据给定的数据构造您的A和B。 -
@FilipeRodrigues 我刚刚使用 serde_json 进行了尝试,它的工作方式与我预期的一样。也许问题更多在于csv?
标签: rust enums deserialization serde