Cow + serde_json

I parse struct with serde_json and then convert the result into some other.
So at the first step I want minimize time and cpu usage taking into consideration that
the mostly I work with strings.
I thought that Cow<str> is ideal type it allocate memory if string contains special symbols,
and just borrow from origin if there is no need for allocation.
This is works for plain &str type:

        let origin = "\"aaa\"";
        let x: &str = serde_json::from_str(origin).unwrap();
        println!("{:?} vs {:?}", origin.as_ptr(), x.as_ptr());

x will point to &origin[1..origin.len()-1].

But for some reason this is not work for Cow:

        let origin = "\"aaa\"";
        let x: std::borrow::Cow<str> = serde_json::from_str(origin).unwrap();
        println!("{:?} vs {:?}", origin.as_ptr(), x.as_ptr());

Cow will always become Cow::Owned instead of Cow::Borrowed.
Is any way to force serde_json allocate memory only if there is need for allocation?

serde_json doesn't do this; it solely depends on the Deserialize impl of Cow, so there's no way to change this.

You could write a newtype wrapper around Cow with the desired behavior.

Actually I found solution after digging issues on github, that point to documentation: serde(borrow) attribute.

        #[derive(Deserialize)]
        struct S<'a> {
            #[serde(borrow)]
            field: Cow<'a, str>,
         }

without serde(borrow) it allocates, and with it no extra allocations happens.

1 Like

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.