gpt4 book ai didi

rust - Rust定制反序列化实现

转载 作者:行者123 更新时间:2023-12-03 11:40:37 25 4
gpt4 key购买 nike

我很难理解如何使用Rust的serde实现自定义映射的反序列化。如果有人可以帮助我解决此示例,我将感到非常高兴:
我有以下结构:

#[derive(Debug, Clone, PartialEq)]
pub struct ConnectorTopics {
pub name: String,
pub topics: Vec<String>,
}
JSON数据采用以下格式:
{
"test-name": {
"topics": [
"topic1",
"topic2"
]
}
}
如您所见, name字段是主题的包装,因此在我的情况下,应反序列化为:
let _ = ConnectorTopics {
name: "test-name".into(),
topics: vec!["topic1".into(), "topic2".into()]
}
我的第一个尝试是在Deserialize实现中使用自定义结构,但是这种方法无法编译,而且似乎也不是正确的方法。
impl<'de> Deserialize<'de> for ConnectorTopics {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
struct Inner {
topics: Vec<String>,
}

let a = deserializer.deserialize_map(HashMap<String, Inner>).unwrap();



let value = Deserialize::deserialize::<HashMap<String, Inner>>(deserializer)?;

let (connector, inner) = value.iter().nth(0).ok_or("invalid")?.0;

Ok(ConnectorTopics {
name: connector,
topics: vec![],
})
}
}

最佳答案

您正在做的是正确的方法,但是您的json很奇怪:

use serde::de;
use serde::Deserialize;
use std::fmt;

#[derive(Debug, Clone, PartialEq)]
pub struct ConnectorTopics {
pub name: String,
pub topics: Vec<String>,
}

#[derive(Debug, Deserialize)]
struct Inner {
topics: Vec<String>,
}

impl<'de> de::Deserialize<'de> for ConnectorTopics {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct ConnectorTopicsVisitor;

impl<'de> de::Visitor<'de> for ConnectorTopicsVisitor {
type Value = ConnectorTopics;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("ConnectorTopics")
}

fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
where
V: de::MapAccess<'de>,
{
if let Some(key) = map.next_key()? {
let value: Inner = map.next_value()?;
if let Some(_) = map.next_key::<&str>()? {
Err(de::Error::duplicate_field("name"))
} else {
Ok(Self::Value {
name: key,
topics: value.topics,
})
}
} else {
Err(de::Error::missing_field("name"))
}
}
}

deserializer.deserialize_map(ConnectorTopicsVisitor {})
}
}

fn main() {
let input = r#"{
"test-name": {
"topics": [
"topic1",
"topic2"
]
}
}"#;

let result: ConnectorTopics = serde_json::from_str(input).unwrap();

let expected = ConnectorTopics {
name: "test-name".into(),
topics: vec!["topic1".into(), "topic2".into()],
};

assert_eq!(result, expected);
}

关于rust - Rust定制反序列化实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66135063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com