JSON Parsing
Recipe | Crates | Categories |
---|---|---|
Parse JSON with json5 | ||
Parse JSON with serde_json | ||
Parse JSON with simd-json |
serde_json
⮳ is the most commonly used crate for JSON Parsing. simd_json
⮳ is optimized for performance.
Parse JSON with serde_json
serde_json
⮳ offers a JSON serialization file format.
use serde::Deserialize; use serde::Serialize; use serde_json::Result; use serde_json::Value; /// Represents a user with a name, age, and a list of phone numbers. #[derive(Deserialize, Serialize, Debug)] struct User { name: String, age: u8, phones: Vec<String>, } /// Demonstrates parsing and serializing JSON data using the `serde_json` crate. /// /// This function parses a JSON string into a `Value` enum and a custom `User` /// struct, then serializes the `User` struct back into a JSON string. fn main() -> Result<()> { let json_str = r#" { "name": "John Doe", "age": 42, "phones": [ "+1 123456789", "+1 234567890" ] } "#; // 1. Parse the JSON string into a `Value` enum. // The `Value` enum can represent any valid JSON value. let parsed: Value = serde_json::from_str(json_str)?; // There are also `from_slice` for parsing from a byte slice `&[u8]` // and `from_reader` for parsing from any `io::Read` type, // such as a `File` or a TCP stream. // 2. Access parts of the data by indexing with square brackets. // The result of square bracket indexing is a borrow, so the type is // `&Value`. let name = parsed["name"].as_str().unwrap(); let age = parsed["age"].as_i64().unwrap(); let phones = parsed["phones"].as_array().unwrap(); println!("Name: {}", name); println!("Age: {}", age); println!("Phones: {:?}", phones); // 3. Parse the JSON string into a custom `User` struct. // The `User` struct must implement the `Deserialize` trait. let user: User = serde_json::from_str(json_str)?; println!("{:?}", user); // 4. Serialize the `User` struct back into a JSON string. let u = serde_json::to_string(&user)?; println!("{u}"); // There are also `serde_json::to_vec`, which serializes to a `Vec<u8>`, // and `serde_json::to_writer`, which serializes to any `io::Write`, // such as a `File` or a TCP stream. Ok(()) }
Parse JSON with json5
json5
⮳ is a Rust JSON5 serializer and deserializer which speaks serde
⮳.
//! This example demonstrates how to parse JSON5 data using the `json5` crate. //! //! [JSON5](https://json5.org) is a superset of JSON that allows for more human-friendly syntax, //! such as comments, unquoted keys, and trailing commas. //! It aims to be easier to write and maintain by hand (e.g. for config files). //! It is not intended to be used for machine-to-machine communication. use serde_json::Value; fn main() { let json5_str = r#"{ // Comments are allowed unquoted: 'and you can use single quotes', trailingComma: ['in arrays', 'like', 'this', ], hexadecimal: 0xDEADbeef, infinity: Infinity, nan: NaN, nested: { pi: 3.141592653, }, 'quoted key': true, // Quoted keys are allowed "backwardsCompatible": "with JSON", }"#; // Parse the JSON5 string into a `serde_json::Value`. match json5::from_str::<Value>(json5_str) { Ok(value) => { println!("Parsed JSON5: {:#?}", value); if let Some(nested) = value.get("nested") { if let Some(pi) = nested.get("pi") { println!("Pi: {}", pi); } } if let Some(hex) = value.get("hexadecimal") { println!("Hex: {}", hex); } if let Some(inf) = value.get("infinity") { println!("Infinity: {}", inf); } if let Some(nan) = value.get("nan") { println!("NaN: {}", nan); } if let Some(unquoted) = value.get("unquoted") { println!("Unquoted: {}", unquoted); } if let Some(quoted_key) = value.get("quoted key") { println!("Quoted Key: {}", quoted_key); } } Err(e) => { eprintln!("Error parsing JSON5: {}", e); } } }
Parse JSON with simd-json
simd-json
⮳ is a high-performance JSON parser based on a port of simdjson
.
//! Example of using the `simd-json` crate for parsing and manipulating JSON //! data. //! //! `simd-json` is a Rust port of the extremely fast simdjson c++ library with //! `serde` compatibility. For best performance, use `mimalloc` or `jemalloc` //! instead of the system allocator used by default. //! //! Example of using `mimalloc`: //! ```rust //! use mimalloc::MiMalloc; //! //! #[global_allocator] //! static GLOBAL: MiMalloc = MiMalloc; //! ``` use simd_json::OwnedValue; use simd_json::derived::ValueObjectAccess; use simd_json::derived::ValueObjectAccessAsArray; use simd_json::derived::ValueObjectAccessAsScalar; use simd_json::prelude::*; fn main() { let mut json_string = br#" { "name": "Alice", "age": 30, "city": "New York", "numbers": [1, 2, 3, 4, 5], "nested": { "value": true } } "# .to_vec(); // Parse the JSON string into a `BorrowedValue`. // `BorrowedValue` is designed for read-only access and avoids unnecessary // copying, making it very fast. match simd_json::to_borrowed_value(&mut json_string) { Ok(json) => { println!("Parsed JSON: {:?}", json); // Access values using `ValueAccess` traits. if let Some(name) = json.get_str("name") { println!("Name: {}", name); } if let Some(age) = json.get_u64("age") { println!("Age: {}", age); } if let Some(city) = json.get_str("city") { println!("City: {}", city); } if let Some(numbers) = json.get_array("numbers") { println!("Numbers: {:?}", numbers); } if let Some(nested) = json.get("nested") { if let Some(nested_value) = nested.get_bool("value") { println!("Nested Value: {}", nested_value); } } } Err(e) => { eprintln!("Error parsing JSON: {}", e); } } // Example using `OwnedValue` (for modifications). // This is slower then the `BorrowedValue` as a tradeoff for getting rid of // lifetimes. let mut owned_json: OwnedValue = simd_json::to_owned_value(&mut json_string).unwrap(); if let Some(name) = owned_json.get_mut("name") { *name = OwnedValue::from("Bob"); } println!("Modified Owned JSON: {}", owned_json); }