Structured Data
Recipe | Crates | Categories |
---|---|---|
Serialize and deserialize unstructured JSON | ||
Deserialize a TOML configuration file | ||
Read and write integers in little-endian byte order |
Serialize and deserialize unstructured JSON
The serde_json
⮳ crate provides a serde_json::from_str
⮳ function to parse a &str
of JSON.
Unstructured JSON can be parsed into a universal serde_json::Value
⮳ type that is able to represent any valid JSON data.
The example below shows a &str
of JSON being parsed. The expected value is declared using the serde_json::json
⮳ macro.
use serde_json::Error; use serde_json::Value; use serde_json::json; fn main() -> Result<(), Error> { let j: &str = r#"{ "userid": 103609, "verified": true, "access_privileges": [ "user", "admin" ] }"#; let parsed: Value = serde_json::from_str(j)?; let expected: Value = json!({ "userid": 103609, "verified": true, "access_privileges": [ "user", "admin" ] }); println!("{}", expected); assert_eq!(parsed, expected); Ok(()) }
Deserialize a TOML configuration file
TOML is a simple, ergonomic, and readable configuration format that is often used by Rust's tooling - for example cargo
.
The following parses some TOML into a universal toml::Value
that is able to represent any valid TOML data.
use toml::Value; use toml::de::Error; fn main() -> Result<(), Error> { // Note the use of a raw string, // so that there is no need to escape the inner double quotes let toml_content = r#" [package] name = "your_package" version = "0.1.0" authors = ["You! <you@example.org>"] [dependencies] serde = "1.0" "#; let package_info: Value = toml::from_str(toml_content)?; assert_eq!(package_info["dependencies"]["serde"].as_str(), Some("1.0")); println!( "Package name: {}", package_info["package"]["name"].as_str().unwrap() ); Ok(()) }
Parse TOML into your own structs using serde
⮳.
use std::collections::HashMap; use serde::Deserialize; use toml::de::Error; #[derive(Deserialize, Debug)] struct Config { package: Package, dependencies: HashMap<String, String>, } #[derive(Deserialize, Debug)] struct Package { name: String, version: String, authors: Vec<String>, } fn main() -> Result<(), Error> { let toml_content = r#" [package] name = "your_package" version = "0.1.0" authors = ["You! <you@example.org>"] [dependencies] serde = "1.0" "#; let package_info: Config = toml::from_str(toml_content)?; println!("{:?}", package_info); assert_eq!(package_info.package.name, "your_package"); assert_eq!(package_info.package.version, "0.1.0"); assert_eq!(package_info.package.authors, vec!["You! <you@example.org>"]); assert_eq!(package_info.dependencies["serde"], "1.0"); Ok(()) }
Read and write integers in little-endian byte order
byteorder
⮳ is a library for reading/writing numbers in big-endian and little-endian. It can reverse the significant bytes of structured data. This may be necessary when receiving information over the network, when bytes received are from another system.
use std::io::Error; use byteorder::LittleEndian; use byteorder::ReadBytesExt; use byteorder::WriteBytesExt; #[derive(Default, PartialEq, Debug)] struct Payload { kind: u8, value: u16, } fn encode(payload: &Payload) -> Result<Vec<u8>, Error> { let mut bytes = vec![]; bytes.write_u8(payload.kind)?; bytes.write_u16::<LittleEndian>(payload.value)?; Ok(bytes) } fn decode(mut bytes: &[u8]) -> Result<Payload, Error> { let payload = Payload { kind: bytes.read_u8()?, value: bytes.read_u16::<LittleEndian>()?, }; Ok(payload) } fn main() -> Result<(), Error> { let original_payload = Payload::default(); let encoded_bytes = encode(&original_payload)?; println!("{:?}", encoded_bytes); let decoded_payload = decode(&encoded_bytes)?; assert_eq!(original_payload, decoded_payload); println!("{:?}", decoded_payload); Ok(()) }