使用serde Rust将数据从记录转置到列,而不需要中间结构



我有两种不同的数据结构:

JSON1:

{
"key1": 40,
"key2": 50
{,
{
"key1": 41,
"key2": 51
}

2:嵌套数组

[[40,50],[41,51]]
目标是将这些数据(我收到的都是Strings)反序列化成一个Struct,如下所示:
struct data {
key1: Vec<i8>,      // -> [40,41]
key2: Vec<i8>       // -> [50,51]
}

我已经有两种方法来反序列化每种类型的数据,但问题是,对于第一个,我必须创建一个中间Struct并将它们收集到Vec中,然后迭代这个Vec,将每个元素推到最终Struct中的特定Vecs。对于第二个,我反序列化到一个Vec<Vec<i8>>,然后再迭代,逐个元素转置到最终的Struct

我通读了所有serde文档,并试图找到示例,但没有中间步骤,无法找到直接推到Struct的最终Vecs的方法。serde支持这个吗?如果有,它是如何实现的?

要做到这一点,您需要为您的数组自定义访问器。下面是一个工作实现。

请注意,虽然我们使用了额外的enumInnerData,但它不需要任何额外的分配,因为这个结构体只在堆栈中使用。对于外部数组的每个元素,InnerData将被反序列化,并将其字段压入Data结构体的字段。

#[serde(untagged)]允许从平面变量反序列化enum(无需在json中指定Map或Array)。

同样,要使用这种类型的反序列化,您需要明确地让Deserializer知道要使用哪个Visitor。如果您的结构是另一个结构的字段之一,您可以使用#[serde(deserialize_with = ...)]属性指定它。

use serde::de;
use serde::de::Deserializer;
use serde::Deserialize;
const A: &str = "[{"key1": 40, "key2": 50}, {"key1": 41, "key2": 51}]";
const B: &str = "[[40, 50], [41, 51]]";
#[derive(Debug, Deserialize)]
struct Data {
key1: Vec<i8>,
key2: Vec<i8>,
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum InnerData {
Map { key1: i8, key2: i8 },
Array(i8, i8),
}
struct DataVisitor;
impl<'de> de::Visitor<'de> for DataVisitor {
type Value = Data;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "invalid input")
}
fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut result = Data {
key1: vec![],
key2: vec![],
};
while let Some(inner) = seq.next_element::<InnerData>()? {
let (k1, k2) = match inner {
InnerData::Map { key1, key2 } => (key1, key2),
InnerData::Array(key1, key2) => (key1, key2),
};
result.key1.push(k1);
result.key2.push(k2);
}
Ok(result)
}
}
fn main() {
let mut deserializer = serde_json::Deserializer::from_str(A);
println!("{:?}", deserializer.deserialize_seq(DataVisitor {}));
let mut deserializer = serde_json::Deserializer::from_str(B);
println!("{:?}", deserializer.deserialize_seq(DataVisitor {}));
}

小提琴:https://play.rust-lang.org/?version=stable&模式= debug&版= 2018,要点= f921adbb490970eb9a8b5ef5f9ab49d0

相关内容

  • 没有找到相关文章

最新更新