serde-rs / bytes

Wrapper types to enable optimized handling of &[u8] and Vec<u8>
Apache License 2.0
306 stars 37 forks source link

Is there a way to borrow when serialize and own when deserialize? #40

Open seekstar opened 1 year ago

seekstar commented 1 year ago

Cow is handled in this way in serde. But serde-bytes deserializes Cow by borrowing. As a result, this compiles:

#[derive(Serialize, Deserialize)]
struct A<'a> {
    a: Cow<'a, [u8]>,
}

But this does not compile:

#[derive(Serialize, Deserialize)]
struct A<'a> {
    #[serde(with = "serde_bytes")]
    a: Cow<'a, [u8]>,
}

The error message generated by compiler:

error: lifetime may not live long enough
 --> src/main.rs:4:21
  |
4 | #[derive(Serialize, Deserialize)]
  |                     ^^^^^^^^^^^
  |                     |
  |                     lifetime `'de` defined here
  |                     associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'de`
5 | struct A<'a> {
  |          -- lifetime `'a` defined here
  |
  = help: consider adding the following bound: `'de: 'a`
  = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

Isn't it more reasonable to handle Cow in a way similar to serde so that deserializing Cow does not borrow?

seekstar commented 1 year ago

I wrote crate CowBytes to solve this problem: https://github.com/seekstar/CowBytes. It seems that it works fine. I would like to submit a PR if the maintainer of serde_bytes consents.