JSON Parsing

RecipeCratesCategories
json5json5cat-parser-implementations
serde_jsonserde_jsoncat-parser-implementations
simd-jsonsimd-jsoncat-parser-implementations

serde_json is the most commonly used crate for JSON Parsing. simd_json is optimized for performance.

Parse JSON with serde_json

serde_json serde_json-crates.io serde_json-github serde_json-lib.rs cat-parser-implementations cat-no-std cat-encoding

serde_json offers a JSON serialization file format.

use serde::Deserialize;
use serde::Serialize;
use serde_json::Result;
use serde_json::Value;

#[derive(Deserialize, Serialize, Debug)]
struct User {
    name: String,
    age: u8,
    phones: Vec<String>,
}

// Deserialize a JSON string
fn main() -> Result<()> {
    let json_str = r#"
    {
        "name": "John Doe",
        "age": 42,
        "phones": [
            "+1 123456789",
            "+1 234567890"
        ]
    }
    "#;

    // Use the `Value` enum to represent any valid JSON value.
    let parsed: Value = serde_json::from_str(json_str)?;
    // There is also `from_slice` for parsing from a byte slice `&[u8]``
    // and `from_reader` for parsing from any `io::Read` like a `File` or a TCP
    // stream.

    // Then 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);

    // Or use a custom `struct` that implements `Deserialize`
    let user: User = serde_json::from_str(json_str)?;
    println!("{:?}", user);

    // Serialize it back to a JSON string.
    let u = serde_json::to_string(&user)?;
    println!("{u}");
    // There is 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 json5-crates.io json5-github json5-lib.rs

json5 is a Rust JSON5 serializer and deserializer which speaks serde.

use json5;
use serde_json::Value;

// JSON5 is an extension to the popular JSON file format that 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. https://json5.org

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 simd-json-crates.io simd-json-github simd-json-lib.rs

simd-json is a high-performance JSON parser based on a port of simdjson.


use simd_json::OwnedValue;
use simd_json::derived::ValueObjectAccess;
use simd_json::derived::ValueObjectAccessAsArray;
use simd_json::derived::ValueObjectAccessAsScalar;
use simd_json::prelude::*;

// `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. For example:
// use mimalloc::MiMalloc;
//
// #[global_allocator]
// static GLOBAL: MiMalloc = MiMalloc;

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.to_string());
}