使用 serde 序列化嵌套的对象数组
Serialize a nested array of objects using serde
根据描述拼图网格的结构,我希望能够序列化嵌套数组:
struct Grid {
display: String,
solution: String,
width: usize,
height: usize,
}
假设 Grid { display: "????", solution: "1234", width: 2, height: 2 }
的结构,我希望输出如下所示(在 JSON 中):
[
[
{
"display": "?",
"solution": "1"
},
{
"display": "?",
"solution": "2"
}
],
[
{
"display": "?",
"solution": "3"
},
{
"display": "?",
"solution": "4"
}
]
]
我的初步实施草案如下所示:
impl<'a> Serialize for Grid<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut columns = serializer.serialize_seq(Some(self.height))?;
for column_index in 0..self.height {
let mut column = columns.serialize_seq(Some(self.width))?;
for row_index in 0..self.width {
let mut cell = column.serialize_map(Some(2))?;
let cell_index = column_index * self.height + row_index;
cell.serialize_entry("display", self.display.chars().nth(cell_index).unwrap())?;
cell.serialize_entry("solution", self.solution.chars().nth(cell_index).unwrap())?;
cell.end()?;
}
column.end()?;
}
columns.end()
}
}
但是,SerializeSeq
没有公开另一个 serialize_seq
方法来进一步嵌套。我怎样才能像这样从一个结构中序列化一个嵌套数组?
您需要几个辅助结构来表示一行和一个单元格:
use serde::*; // 1.0.130
use serde::ser::*;
struct Grid {
display: String,
solution: String,
width: usize,
height: usize,
}
impl Serialize for Grid {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut rows = serializer.serialize_seq (Some (self.height))?;
for idx in 0..self.height {
rows.serialize_element (&Row { grid: self, start_idx: idx * self.width })?;
}
rows.end()
}
}
struct Row<'a> {
grid: &'a Grid,
start_idx: usize,
}
impl<'a> Serialize for Row<'a> {
fn serialize<S: Serializer> (&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut row = serializer.serialize_seq (Some (self.grid.width))?;
for idx in 0..self.grid.width {
row.serialize_element (&Cell { grid: self.grid, idx: self.start_idx + idx })?;
}
row.end()
}
}
struct Cell<'a> {
grid: &'a Grid,
idx: usize,
}
impl<'a> Serialize for Cell<'a> {
fn serialize<S: Serializer> (&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut cell = serializer.serialize_map (Some (2))?;
cell.serialize_entry ("display", &self.grid.display.chars().nth (self.idx).unwrap())?;
cell.serialize_entry ("solution", &self.grid.solution.chars().nth (self.idx).unwrap())?;
cell.end()
}
}
具有 display 和 solution 作为字段的辅助结构 Cell 将使序列化更容易。然后,您可以使用包括 zip 和 map 在内的迭代器适配器以功能方式构建单元格列表,并显示网格的值.然后,使用chunks适配器,将一维向量按行大小转换为二维向量。最后,使用宏json!生成 json 字符串。
use serde::{Deserialize, Serialize};
use serde_json::json;
struct Grid {
display: String,
solution: String,
width: usize,
height: usize,
}
#[derive(Serialize, Deserialize)]
struct Cell {
display: char,
solution: char,
}
fn main() {
let grid = Grid { display: "????".to_string(), solution: "1234".to_string(), width: 2, height: 2 };
let cells :Vec<Cell> = grid.display.chars().zip(grid.solution.chars()).map(|(a, b)| Cell {display: a, solution: b} ).collect();
let rows : Vec<&[Cell]>= cells.chunks(grid.width).collect();
print!("{:#}", json!(rows));
}
根据描述拼图网格的结构,我希望能够序列化嵌套数组:
struct Grid {
display: String,
solution: String,
width: usize,
height: usize,
}
假设 Grid { display: "????", solution: "1234", width: 2, height: 2 }
的结构,我希望输出如下所示(在 JSON 中):
[
[
{
"display": "?",
"solution": "1"
},
{
"display": "?",
"solution": "2"
}
],
[
{
"display": "?",
"solution": "3"
},
{
"display": "?",
"solution": "4"
}
]
]
我的初步实施草案如下所示:
impl<'a> Serialize for Grid<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut columns = serializer.serialize_seq(Some(self.height))?;
for column_index in 0..self.height {
let mut column = columns.serialize_seq(Some(self.width))?;
for row_index in 0..self.width {
let mut cell = column.serialize_map(Some(2))?;
let cell_index = column_index * self.height + row_index;
cell.serialize_entry("display", self.display.chars().nth(cell_index).unwrap())?;
cell.serialize_entry("solution", self.solution.chars().nth(cell_index).unwrap())?;
cell.end()?;
}
column.end()?;
}
columns.end()
}
}
但是,SerializeSeq
没有公开另一个 serialize_seq
方法来进一步嵌套。我怎样才能像这样从一个结构中序列化一个嵌套数组?
您需要几个辅助结构来表示一行和一个单元格:
use serde::*; // 1.0.130
use serde::ser::*;
struct Grid {
display: String,
solution: String,
width: usize,
height: usize,
}
impl Serialize for Grid {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut rows = serializer.serialize_seq (Some (self.height))?;
for idx in 0..self.height {
rows.serialize_element (&Row { grid: self, start_idx: idx * self.width })?;
}
rows.end()
}
}
struct Row<'a> {
grid: &'a Grid,
start_idx: usize,
}
impl<'a> Serialize for Row<'a> {
fn serialize<S: Serializer> (&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut row = serializer.serialize_seq (Some (self.grid.width))?;
for idx in 0..self.grid.width {
row.serialize_element (&Cell { grid: self.grid, idx: self.start_idx + idx })?;
}
row.end()
}
}
struct Cell<'a> {
grid: &'a Grid,
idx: usize,
}
impl<'a> Serialize for Cell<'a> {
fn serialize<S: Serializer> (&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut cell = serializer.serialize_map (Some (2))?;
cell.serialize_entry ("display", &self.grid.display.chars().nth (self.idx).unwrap())?;
cell.serialize_entry ("solution", &self.grid.solution.chars().nth (self.idx).unwrap())?;
cell.end()
}
}
具有 display 和 solution 作为字段的辅助结构 Cell 将使序列化更容易。然后,您可以使用包括 zip 和 map 在内的迭代器适配器以功能方式构建单元格列表,并显示网格的值.然后,使用chunks适配器,将一维向量按行大小转换为二维向量。最后,使用宏json!生成 json 字符串。
use serde::{Deserialize, Serialize};
use serde_json::json;
struct Grid {
display: String,
solution: String,
width: usize,
height: usize,
}
#[derive(Serialize, Deserialize)]
struct Cell {
display: char,
solution: char,
}
fn main() {
let grid = Grid { display: "????".to_string(), solution: "1234".to_string(), width: 2, height: 2 };
let cells :Vec<Cell> = grid.display.chars().zip(grid.solution.chars()).map(|(a, b)| Cell {display: a, solution: b} ).collect();
let rows : Vec<&[Cell]>= cells.chunks(grid.width).collect();
print!("{:#}", json!(rows));
}