2

我正在尝试使用serde_json将数组数组(表示字符串单元格表)反序列化为 Rust 中的自定义结构。我知道serde_json::Value对于这种简单的情况,使用就足够了,但我想构造一个自定义类型。

use serde::{Deserialize};
use serde_json::{self, Result};

#[derive(Deserialize, Debug)]
pub struct Row {
    pub cells: Vec<String>,
}

#[derive(Deserialize, Debug)]
pub struct Table {
    pub rows: Vec<Row>,
}

impl Table {

    pub fn new(data: &str) -> Result<Table> {
        let table = serde_json::from_str(data);
        table
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn from_json_string() {
        let test_table = r#"
[
  ["0,1", "0,2", "0,3"], 
  ["1,1", "1,2", "1,3"]
]
"#;
        let table: Table = Table::new(&test_table).unwrap();
        assert_eq!(table.rows.len(), 2);
    }

}

使用此代码,测试会出现Error("invalid type: string \"0,1\", expected struct Row".

我应该如何为这个简单的 JSON 字符串定义结构?

4

2 回答 2

3

您想将标签添加#[serde(transparent)]到结构中

use serde::{Deserialize};
use serde_json::{self, Result};

#[derive(Deserialize, Debug)]
#[serde(transparent)] 
pub struct Row {
    pub cells: Vec<String>,
}

#[derive(Deserialize, Debug)]
#[serde(transparent)] 
pub struct Table {
    pub rows: Vec<Row>,
}

impl Table {

    pub fn new(data: &str) -> Result<Table> {
        let table = serde_json::from_str(data);
        table
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn from_json_string() {
        let test_table = r#"
[
  ["0,1", "0,2", "0,3"], 
  ["1,1", "1,2", "1,3"]
]
"#;
        let table: Table = Table::new(&test_table).unwrap();
        assert_eq!(table.rows.len(), 2);
    }

}

操场

#[serde(transparent)]

序列化和反序列化具有一个字段的新类型结构或大括号结构,就像它的一个字段被自己序列化和反序列化一样。类似于#[repr(transparent)]。

取自此处的属性页面:https ://serde.rs/container-attrs.html

于 2020-01-23T08:02:38.807 回答
-1

您的输入不是有效的 JSON,因为您正在使用serde_json它,所以输入实际上是 JSON 是明智的。

您可以将代码更改为类似于以下代码的内容:

#[test]
fn from_json_string() {
    let test_table = r#"
    {
        "rows" : [
            {
                "cells" : ["1", "2"]
            },
            {
                "cells" : ["3", "4"]
            }
        ]
    }"#;

    let table: Table = Table::new(&test_table).unwrap();
    assert_eq!(table.rows.len(), 2);
}
于 2020-01-23T08:22:44.800 回答