1 普通版本
结构体和json字符串里的每个字段一一对应
[dependencies]
serde_derive = "1.0.130"
serde = "1.0.130"
serde_json = "1.0.67"
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Stu {
name: String,
id: i32,
score: i32
}
fn main() {
let stu1 = Stu { name: "张三".to_string(), id: 007, score: 100 };
let serialized = serde_json::to_string(&stu1).unwrap();//序列化,结构体变量转json字符串
println!("serialized = {}", serialized);
let stu2: Stu = serde_json::from_str(&serialized).unwrap();//反序列化,json字符串转结构体变量,需要指定结构体变量stu2的类型为Stu,而且要求Stu这个结构体变量的字段和Json字符串的字段一一对应
println!("deserialized = {:#?}", stu2);
}
2 特殊类型
结构体和json字符串里的每个字段并非一一对应,结构体里有些字段,在json字符串中没有,这时候就要把没有出现的字段类型改为Option。
//mytest/Cargo.toml
[package]
name = "mytest"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde_derive = "1.0.130"
serde = "1.0.130"
serde_json = "1.0.67"
//mytest/src/lib.rs
#[macro_use]
extern crate serde_derive;
use std::fmt::Debug;
#[derive(Serialize, Deserialize, Debug)]
pub struct Address {
province: String,
city: String,
house_number: Option<String>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct BirthDate (pub u8,pub u8,pub u8);
#[derive(Serialize, Deserialize, Debug)]
pub struct UserInfo{
username: String,
password : String,
pub birth_date: Option<BirthDate>,
school: String,
address : Option<Address>,
}
//mytest/src/main.rs
use mytest::UserInfo;
use mytest::BirthDate;
use serde;
use serde_json;
fn main() {
let json =r#"{
"username": "hhh",
"password": "123456",
"school": "csust",
"address": {
"province": "hn",
"city": "cs",
"house_number": "9527"
}
}"#;
let mut user_info: UserInfo = serde_json::from_str(&json).unwrap(); //反序列化
println!("{:#?}",user_info); //使用{} 这个format的话,要derive Display trait ,Display这个trait里没有默认实现,所以需要自己取实现
//使用 {:?} or {:#?} (后者是有换行功能) 这两个format的话,要derive Debug trait,Debug trait有默认实现
user_info.birth_date = Some(BirthDate(3,6,8));
println!("{:#?}",user_info);
let json = serde_json::to_string(&user_info).unwrap(); //序列化
println!("{:#?}",user_info);
}
//output
/*
UserInfo {
username: "hhh",
password: "123456",
birth_date: None,
school: "csust",
address: Some(
Address {
province: "hn",
city: "cs",
house_number: Some(
"9527",
),
},
),
}
UserInfo {
username: "hhh",
password: "123456",
birth_date: Some(
BirthDate(
3,
6,
8,
),
),
school: "csust",
address: Some(
Address {
province: "hn",
city: "cs",
house_number: Some(
"9527",
),
},
),
}
UserInfo {
username: "hhh",
password: "123456",
birth_date: Some(
BirthDate(
3,
6,
8,
),
),
school: "csust",
address: Some(
Address {
province: "hn",
city: "cs",
house_number: Some(
"9527",
),
},
),
}
*/
*/
3 json转Value类型
value类型是万能类型,什么类型的值都能装,在处理把json字符串反序列化的时候很个很好用的容器。
[dependencies] //使用了第三方包,必须加包的依赖
serde_json = "1.0.67"
//src/main.rs
//use serde_json::json; 把使用的条目导入作用域相当于,把这个json宏和Vaule结构的定义在这里展开,那么相当于main函数和json宏的定义处于同一个模块内,同以级别,main里可以直接这样使用let v: Value = json!({"username": "123"});
//use serde_json::Value; 不把使用的条目导入作用域也可以,不过使用的时候就要从crate根(可以写crate字面值(当这个crate是lib.rs对应的crate时可以这样),和crate名)开始写
let s: String = "fuck".to_string();
let v: serde_json::Value = serde_json::json!({
"name" : s,
"sex" : s
});
println!("{}",s);
println!("{:#?}",v);
}
4 Value 转结构体
let response: OperationResponse = serde_json::from_value(response)?;
5 取Serde_json::Value 中的值,不用模式匹配一层一层打开
use serde_json::{Result, Value};
fn untyped_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
// Parse the string of data into serde_json::Value.
let v: Value = serde_json::from_str(data)?;
// let v = serde_json::from_str::<Value>(data)?; // 或者可以这样写
// Access parts of the data by indexing with square brackets.
//对于Value::Object(Map<String,Value>和Value::Array(Vec<Value>),取里面的值可以用索引一次取两层,没必要用if let 匹配取
println!(" {:#?} \n \n {:#?}", v["name"], v["phones"][0]);
Ok(())
}
//output
String(
"John Doe",
)
String(
"+44 1234567",
)
6 #[serde(rename(deserialize = “XXX”, serialize = “XXX”))]的使用
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)] //to do实现display 做笔记
struct Stu {
#[serde(rename(deserialize = "deserialize_name", serialize = "serialize_name"))]
name: String,
#[serde(rename(deserialize = "deserialize_id", serialize = "serialize_id"))]
id: i32,
#[serde(rename(deserialize = "deserialize_score", serialize = "serialize_score"))]
score: i32,
#[serde(rename(deserialize = "country", deserialize = "province", deserialize = "city", deserialize = "block"))]
home: String,
}
#[test]
fn test3() {
let stu = Stu {
name: "tony".to_string(),
id: 9527,
score: 100,
home: "Hunan".to_string(),
};
let serialize = serde_json::to_string(&stu).unwrap();
println!("{}",serialize);
let deserialize = serde_json::from_str::<Stu>("{\"serialize_name\":\"tony\",\"serialize_id\":9527,\"serialize_score\":100}"); //少了rust 结构体的 home 字段
if deserialize.is_err()
{
println!("反序列失败");
} else {
println!("{:#?}",deserialize.unwrap());
}
let deserialize = serde_json::from_str::<Stu>("{\"deserialize_name\":\"tony\",\"deserialize_id\":9527,\"deserialize_score\":100,\"country\":\"CN\"}");
if deserialize.is_err()
{
println!("反序列失败");
} else {
println!("{:#?}",deserialize.unwrap());
}
let deserialize = serde_json::from_str::<Stu>(r#"{"deserialize_name":"tony","deserialize_id":9527,"deserialize_score":100,"block":"CS"}"#);
if deserialize.is_err()
{
println!("反序列失败");
} else {
println!("{:#?}",deserialize.unwrap());
}
}
/*
output
{"serialize_name":"tony","serialize_id":9527,"serialize_score":100,"home":"Hunan"}
反序列失败
Stu {
name: "tony",
id: 9527,
score: 100,
home: "CN",
}
Stu {
name: "tony",
id: 9527,
score: 100,
home: "CS",
}
*/
7 浅谈json string
json string 有两种写法
"{\"deserialize_name\":\"tony\",\"deserialize_id\":9527,\"deserialize_score\":100,\"country\":\"CN\"}"
这种写法使用了转义字符\"
把"
的意思由字符串结束转成了双引号字符(成为字符串的许多字符里的一份子)r#"{"deserialize_name":"tony","deserialize_id":9527,"deserialize_score":100,"block":"CS"}"#
这种是用了r#"
和"#
把字符串包起来,这种写法较为简单