介紹
serde crate 是 Serde 生態的核心。serde_derive crate 提供必要的工具,使用過程宏來派生 Serialize 和 Deserialize。但是serde只提供序列化和反序列化的框架,具體的操作還需要依賴具體的包,如serde_json和serde_yaml等。
下面透過兩個例子來介紹。
序列化與序列化示例
簡單例項一
建立工程
cargo new use_ser
修改Cargo.toml檔案,新增依賴
[dependencies] serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.52" serde_yaml = "0.8.11"
編寫原始碼:
use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize, Debug)] struct ServerConfig { workers: u64, ignore: bool, auth_server: Option<String>, } fn main() { let config = ServerConfig { workers: 100, ignore: false, auth_server: Some(String::from("auth.server.io")), }; { println!("To and from Json"); let serialized = serde_json::to_string(&config).unwrap(); println!("serialized: {}", serialized); println!(""); let deserialized: ServerConfig = serde_json::from_str(&serialized).unwrap(); println!("deserialized: {:#?}", deserialized); } println!(""); println!(""); { println!("To and from Yaml"); let serialized = serde_yaml::to_string(&config).unwrap(); println!("serialized: {}", serialized); println!(""); let deserialized: ServerConfig = serde_yaml::from_str(&serialized).unwrap(); println!("deserialized: {:#?}", deserialized); } }
執行結果
To and from Json serialized: {"workers":100,"ignore":false,"auth_server":"auth.server.io"} deserialized: ServerConfig { workers: 100, ignore: false, auth_server: Some( "auth.server.io", ), } To and from Yaml serialized: --- workers: 100 ignore: false auth_server: auth.server.io deserialized: ServerConfig { workers: 100, ignore: false, auth_server: Some( "auth.server.io", ), }
網路例子
server端
建立工程
cargo new server
修改Cargo.toml檔案,新增依賴
[dependencies] serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.52"
原始碼
use serde::{Deserialize, Serialize}; use serde_json; use std::io::{self, prelude::*, BufReader, Write}; use std::net::{TcpListener, TcpStream}; use std::{str, thread}; #[derive(Debug, Serialize, Deserialize)] struct Point3D { x: u32, y: u32, z: u32, } fn handle_client(stream: TcpStream) -> io::Result<()> { println!("Incoming connection from: {}", stream.peer_addr()?); let mut data = Vec::new(); let mut stream = BufReader::new(stream); loop { data.clear(); let bytes_read = stream.read_until(b'\n', &mut data)?; if bytes_read == 0 { return Ok(()); } let input: Point3D = serde_json::from_slice(&data)?; let value = input.x.pow(2) + input.y.pow(2) + input.z.pow(2); stream.get_mut().write(&(serde_json::to_vec(&(f64::from(value).sqrt()))?))?; stream.get_mut().write(&("\n".as_bytes()))?; stream.get_mut().flush()?; // write!(stream.get_mut(), "{}", f64::from(value).sqrt())?; // write!(stream.get_mut(), "{}", "\n")?; } } fn main() -> io::Result<()> { let listener = TcpListener::bind("0.0.0.0:8080")?; for stream in listener.incoming() { match stream { Err(e) => eprintln!("failed: {}", e), Ok(stream) => { thread::spawn(move || { handle_client(stream).unwrap_or_else(|error| eprintln!("{:?}", error)); }); } } } Ok(()) }
client端
建立工程
cargo new client
修改Cargo.toml檔案,新增依賴
[dependencies] serde = { version = "1.0.106", features = ["derive"] } serde_json = "1.0.52"
原始碼
use serde::{Deserialize, Serialize}; use serde_json; use std::io::{self, prelude::*, BufReader, Write}; use std::net::TcpStream; use std::str; #[derive(Debug, Serialize, Deserialize)] struct Point3D { x: u32, y: u32, z: u32, } fn main() -> io::Result<()> { let mut stream = TcpStream::connect("127.0.0.1:8080")?; println!("Please provide a 3D point as three comma separated integers"); loop { let mut input = String::new(); let mut buffer: Vec<u8> = Vec::new(); io::stdin() .read_line(&mut input) .expect("Failed to read from stdin"); let parts: Vec<&str> = input.trim_matches('\n').split(',').collect(); let point = Point3D { x: parts[0].parse().unwrap(), y: parts[1].parse().unwrap(), z: parts[2].parse().unwrap(), }; stream .write_all(serde_json::to_string(&point).unwrap().as_bytes()) .expect("Failed to write to server"); stream.write_all(b"\n").expect("Failed to write to server"); let mut reader = BufReader::new(&stream); reader .read_until(b'\n', &mut buffer) .expect("Could not read into buffer"); let input = str::from_utf8(&buffer).expect("Could not write buffer as string"); if input == "" { eprintln!("Empty response from server"); } print!("Response from server {}", input); } }
執行方式
先起server端
cargo run server
起客戶端
cargo run client
客戶端如下:
Please provide a 3D point as three comma separated integers 1,2,3 //輸入1,2,3 Response from server 3.7416573867739413 //返回計算結果
本作品採用《CC 協議》,轉載必須註明作者和本文連結