Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Serde format for in situ JSON deserialization #7

@dtolnay

Description

@dtolnay

Originally filed as serde-rs/json#318, but since this will involve quite a bit more unsafe code than currently exists in serde_json I think it could be better to put in a separate crate. Much of the implementation can be drawn from serde_json.

The idea is to implement a function like:

pub fn from_mut_str<'a, T>(s: &'a mut str) -> Result<T>
where
    T: Deserialize<'a>;

backed by a Serde Deserializer that knows how to unescape JSON strings in place.

#[derive(Deserialize)]
struct S<'a> {
    msg: &'a str,
}
// input
"{\"msg\":\"abc\\nxyz\"}"

// after unescaping in place
"{\"msg\":\"abc\nxyzz\"}"
            ^^^^^^^^ output &str
fn main() {
    let mut j = "{\"msg\":\"abc\\nxyz\"}".to_owned();
    let actual = from_mut_str::<S>(&mut j).unwrap();

    let expected = S { msg: "abc\nxyz" };
    assert_eq!(actual, expected);
    assert_eq!(actual.msg.as_ptr(), j[8..].as_ptr());
    assert_eq!(j, "{\"msg\":\"abc\nxyzz\"}"); // not a commitment in the API, but in practice this is what it will be
}

In the example, the incoming bytes in memory would contain a subslice looking like:

    +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
... |  :  |  "  |  a  |  b  |  c  |  \  |  n  |  x  |  y  |  z  |  "  |  }  | ...
    +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+

and JSON deserialization shuffles them to lay out the correct output string bytes in place while modifying the minimum amount of memory:

                +-----+-----+-----+-----+-----+-----+-----+
            ... |  a  |  b  |  c  | \n  |  x  |  y  |  z  | ...
                +-----+-----+-----+-----+-----+-----+-----+

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions