Zero-copy deserialization (serde_json)

I have a json with the following format:

{
    "jsonrpc": "2.0",
    "id": 2,
    "result": {
        "contents": {
            "kind": "plaintext",
            "value": "std::os::raw\n\n // size = 4, align = 0x4\npub type c_uint = core::ffi::c_uint"
        },
        "range": {
            "start": {
                "line": 1,
                "character": 33
            },
            "end": {
                "line": 1,
                "character": 39
            }
        }
    }
}

I wish to do a zero-copy deserialization using serde_json. Here are the structs I created:

#[derive(Debug, Clone, Deserialize, Serialize)]
struct HoverResponse<'a> {
    jsonrpc: &'a str,
    id: usize,
    result: HResult<'a>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
struct HResult<'a> {
    contents: Contents<'a>,
    range: Range,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
struct Contents<'a> {
    kind: &'a str,
    value: &'a str,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
struct Range {
    start: Position,
    end: Position,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
struct Position {
    line: usize,
    character: usize,
}

However, I get the following error regarding the lifetimes.

error: lifetime may not live long enough
   --> aunor-utils/src/bin/lsp_test.rs:175:5
    |
173 | #[derive(Debug, Clone, Deserialize, Serialize)]
    |                        ----------- lifetime `'de` defined here
174 | struct HResult<'a> {
    |                -- lifetime `'a` defined here
175 |     contents: Contents<'a>,
    |     ^^^^^^^^^^^^^^^^^^^^^^ requires that `'de` must outlive `'a`
    |
    = help: consider adding the following bound: `'de: 'a`

I am unable to see what I am doing wrong here. Any help is greatly appreciated :pray:

The macro only knows how to recognize a few hard-coded borrowing types. For the others you have to annotate them as borrowing.

 #[derive(Debug, Clone, Deserialize, Serialize)]
 struct HoverResponse<'a> {
     jsonrpc: &'a str,
     id: usize,
+    #[serde(borrow)]
     result: HResult<'a>,
 }

 #[derive(Debug, Clone, Deserialize, Serialize)]
 struct HResult<'a> {
+    #[serde(borrow)]
     contents: Contents<'a>,
     range: Range,
 }

Side-note: JSON cannot be zero-copy in the general case due to escape sequences.

6 Likes

Thank you!!
Even more so, for the "side-note"!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.