以不同的格式反序列化 JSON - Serde_JSON
Deserialising JSON in a different format - Serde_JSON
我正在尝试从具有以下尺寸的 Rust 文件中读取 JSON:
{
"DIPLOBLASTIC":"Characterizing the ovum when it has two primary germinallayers.",
"DEFIGURE":"To delineate. [Obs.]These two stones as they are here defigured. Weever.",
"LOMBARD":"Of or pertaining to Lombardy, or the inhabitants of Lombardy.",
"BAHAISM":"The religious tenets or practices of the Bahais."
}
我想将每个单词及其描述存储在一个向量中(这是一个刽子手游戏)。如果文件格式如下,我可以读取文件:
[
{
"word": "DIPLOBLASTIC",
"description": "Characterizing the ovum when it has two primary germinallayers."
},
{
"word": "DEFIGURE",
"description": "To delineate. [Obs.]These two stones as they are here defigured. Weever."
}
]
我使用以下代码执行此操作:
#[macro_use]
extern crate serde_derive;
use serde_json::Result;
use std::fs;
#[derive(Deserialize, Debug)]
struct Word {
word: String,
description: String,
}
fn main() -> Result<()> {
let data = fs::read_to_string("src/words.json").expect("Something went wrong...");
let words: Vec<Word> = serde_json::from_str(&data)?;
println!("{}", words[0].word);
Ok(())
}
但是我想弄清楚如何在第二个 JSON 示例中保持 JSON 文件的原始格式而不将其转换为文字和描述。
有没有办法使用现有的 JSON 格式,或者我需要重新格式化吗?
您可以将地图收集到 HashMap
或 BTreeMap
中,然后使用其键值对来制作词向量。
fn main() -> Result<()> {
let data = r#"{
"DIPLOBLASTIC":"Characterizing the ovum when it has two primary germinallayers.",
"DEFIGURE":"To delineate. [Obs.]These two stones as they are here defigured. Weever.",
"LOMBARD":"Of or pertaining to Lombardy, or the inhabitants of Lombardy.",
"BAHAISM":"The religious tenets or practices of the Bahais."
}"#;
let words: std::collections::BTreeMap<String, String> = serde_json::from_str(data)?;
let words = words
.into_iter()
.map(|(word, description)| Word { word, description })
.collect::<Vec<_>>();
println!("{:#?}", words);
Ok(())
}
如果您想保存分配和迭代,您可以使用自定义反序列化实现来实现:
#[macro_use]
extern crate serde_derive;
use std::fmt;
use serde::de::{Deserialize, Visitor, MapAccess};
#[derive(Deserialize, Debug)]
struct Word {
word: String,
description: String,
}
#[derive(Debug)]
struct WordList {
list: Vec<Word>,
}
#[derive(Debug)]
struct WordListVisitor;
impl<'de> Visitor<'de> for WordListVisitor {
type Value = WordList;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string->string map")
}
fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut list = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some((word, description)) = access.next_entry()? {
list.push(Word { word, description });
}
Ok(WordList { list })
}
}
impl<'de> Deserialize<'de> for WordList {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_map(WordListVisitor)
}
}
fn main() -> serde_json::Result<()> {
let data = r#"{
"DIPLOBLASTIC":"Characterizing the ovum when it has two primary germinallayers.",
"DEFIGURE":"To delineate. [Obs.]These two stones as they are here defigured. Weever.",
"LOMBARD":"Of or pertaining to Lombardy, or the inhabitants of Lombardy.",
"BAHAISM":"The religious tenets or practices of the Bahais."
}"#;
let words: WordList = serde_json::from_str(data)?;
println!("{:#?}", words);
Ok(())
}
我正在尝试从具有以下尺寸的 Rust 文件中读取 JSON:
{
"DIPLOBLASTIC":"Characterizing the ovum when it has two primary germinallayers.",
"DEFIGURE":"To delineate. [Obs.]These two stones as they are here defigured. Weever.",
"LOMBARD":"Of or pertaining to Lombardy, or the inhabitants of Lombardy.",
"BAHAISM":"The religious tenets or practices of the Bahais."
}
我想将每个单词及其描述存储在一个向量中(这是一个刽子手游戏)。如果文件格式如下,我可以读取文件:
[
{
"word": "DIPLOBLASTIC",
"description": "Characterizing the ovum when it has two primary germinallayers."
},
{
"word": "DEFIGURE",
"description": "To delineate. [Obs.]These two stones as they are here defigured. Weever."
}
]
我使用以下代码执行此操作:
#[macro_use]
extern crate serde_derive;
use serde_json::Result;
use std::fs;
#[derive(Deserialize, Debug)]
struct Word {
word: String,
description: String,
}
fn main() -> Result<()> {
let data = fs::read_to_string("src/words.json").expect("Something went wrong...");
let words: Vec<Word> = serde_json::from_str(&data)?;
println!("{}", words[0].word);
Ok(())
}
但是我想弄清楚如何在第二个 JSON 示例中保持 JSON 文件的原始格式而不将其转换为文字和描述。
有没有办法使用现有的 JSON 格式,或者我需要重新格式化吗?
您可以将地图收集到 HashMap
或 BTreeMap
中,然后使用其键值对来制作词向量。
fn main() -> Result<()> {
let data = r#"{
"DIPLOBLASTIC":"Characterizing the ovum when it has two primary germinallayers.",
"DEFIGURE":"To delineate. [Obs.]These two stones as they are here defigured. Weever.",
"LOMBARD":"Of or pertaining to Lombardy, or the inhabitants of Lombardy.",
"BAHAISM":"The religious tenets or practices of the Bahais."
}"#;
let words: std::collections::BTreeMap<String, String> = serde_json::from_str(data)?;
let words = words
.into_iter()
.map(|(word, description)| Word { word, description })
.collect::<Vec<_>>();
println!("{:#?}", words);
Ok(())
}
如果您想保存分配和迭代,您可以使用自定义反序列化实现来实现:
#[macro_use]
extern crate serde_derive;
use std::fmt;
use serde::de::{Deserialize, Visitor, MapAccess};
#[derive(Deserialize, Debug)]
struct Word {
word: String,
description: String,
}
#[derive(Debug)]
struct WordList {
list: Vec<Word>,
}
#[derive(Debug)]
struct WordListVisitor;
impl<'de> Visitor<'de> for WordListVisitor {
type Value = WordList;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string->string map")
}
fn visit_map<A: MapAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut list = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some((word, description)) = access.next_entry()? {
list.push(Word { word, description });
}
Ok(WordList { list })
}
}
impl<'de> Deserialize<'de> for WordList {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_map(WordListVisitor)
}
}
fn main() -> serde_json::Result<()> {
let data = r#"{
"DIPLOBLASTIC":"Characterizing the ovum when it has two primary germinallayers.",
"DEFIGURE":"To delineate. [Obs.]These two stones as they are here defigured. Weever.",
"LOMBARD":"Of or pertaining to Lombardy, or the inhabitants of Lombardy.",
"BAHAISM":"The religious tenets or practices of the Bahais."
}"#;
let words: WordList = serde_json::from_str(data)?;
println!("{:#?}", words);
Ok(())
}