serde_stacker

Crates.ioserde_stacker
lib.rsserde_stacker
version0.1.11
sourcesrc
created_at2019-01-13 19:22:31.959581
updated_at2024-01-02 17:43:11.470984
descriptionSerde adapter that avoids stack overflow by dynamically growing the stack
homepage
repositoryhttps://github.com/dtolnay/serde-stacker
max_upload_size
id108368
size56,400
Lanthanum (github:zxtn:lanthanum)

documentation

https://docs.rs/serde_stacker

README

Serde stack growth adapter

github crates.io docs.rs build status

This crate provides a Serde adapter that avoids stack overflow by dynamically growing the stack.

Be aware that you may need to protect against other recursive operations outside of serialization and deserialization when working with deeply nested data, including, but not limited to, Display and Debug and Drop impls.

[dependencies]
serde = "1.0"
serde_stacker = "0.1"

Deserialization example

use serde::Deserialize;
use serde_json::Value;

fn main() {
    let mut json = String::new();
    for _ in 0..10000 {
        json = format!("[{}]", json);
    }

    let mut deserializer = serde_json::Deserializer::from_str(&json);
    deserializer.disable_recursion_limit();
    let deserializer = serde_stacker::Deserializer::new(&mut deserializer);
    let value = Value::deserialize(deserializer).unwrap();

    carefully_drop_nested_arrays(value);
}

fn carefully_drop_nested_arrays(value: Value) {
    let mut stack = vec![value];
    while let Some(value) = stack.pop() {
        if let Value::Array(array) = value {
            stack.extend(array);
        }
    }
}

Serialization example

use serde::Serialize;
use serde_json::Value;

fn main() {
    let mut value = Value::Null;
    for _ in 0..10000 {
        value = Value::Array(vec![value]);
    }

    let mut out = Vec::new();
    let mut serializer = serde_json::Serializer::new(&mut out);
    let serializer = serde_stacker::Serializer::new(&mut serializer);
    let result = value.serialize(serializer);

    carefully_drop_nested_arrays(value);

    result.unwrap();
    assert_eq!(out.len(), 10000 + "null".len() + 10000);
}

fn carefully_drop_nested_arrays(value: Value) {
    let mut stack = vec![value];
    while let Some(value) = stack.pop() {
        if let Value::Array(array) = value {
            stack.extend(array);
        }
    }
}

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Commit count: 76

cargo fmt