This repository was archived by the owner on Jul 9, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 7
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
Serde format for in situ JSON deserialization #7
Copy link
Copy link
Open
Description
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 &strfn 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 | ...
+-----+-----+-----+-----+-----+-----+-----+
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels