quininer / cbor4ii

CBOR: Concise Binary Object Representation
MIT License
54 stars 5 forks source link

Support zero copy using the bytes crate #25

Closed dignifiedquire closed 1 year ago

dignifiedquire commented 1 year ago

I have a few cases where I would like to deserialize cbor from an incoming BytesMut into cbor struct that looks sth like this

struct Foo {
   pub data: Bytes,
   // other small fields
}

where I very much need to avoid copying the data (that data is on the order of 100s of MB often).

I tried hacking sth together, but didn't quite get anywhere, so wondering if you could give me some hints on how this could be done. Thanks.

bdbai commented 1 year ago

Please take a look at serde_bytes.

dignifiedquire commented 1 year ago

@bdbai I don’t understand how serde_bytes would be useful here. The bytes crate is using refcounted slices under the hood, which is sth very different

quininer commented 1 year ago

You can do this manually, like

#[derive(Deserialize)]
struct Foo<'a> {
    #[serde(with = "serde_bytes")]
    pub data: &'a [u8]
}

let bytes: Bytes = get_bytes();
let foo: Foo<'_> = from_slice(&bytes).unwrap();
let data: Bytes = bytes.slice_ref(foo.data);

The trick is to use the Bytes::slice_ref method.

dignifiedquire commented 1 year ago

Thanks, that works, a little cumbersome with nested types, but it does work.