google / zerocopy

https://docs.rs/zerocopy
Apache License 2.0
1.03k stars 80 forks source link

Integration with the `bytes` crates #1444

Open dignifiedquire opened 2 weeks ago

dignifiedquire commented 2 weeks ago

A lot of my networking code uses bytes to handle efficient storing of incoming and outgoing packets. I would like to transition more of that code to use zerocopy, but for that some integration would be required.

The following example is for the parsing side of what I would like to do, but this fails as ByteSlice is not implemented for bytes::Bytes or bytes::BytesMut.

I can't implement this in my own crate, as both the type and the trait are in 3rd party crates.

use zerocopy::{AsBytes, ByteSlice, FromBytes, FromZeroes, Ref, Unaligned};
use bytes::Bytes;

#[derive(FromZeroes, FromBytes, AsBytes, Unaligned)]
#[repr(C)]
struct UdpHeader {
    src_port: [u8; 2],
    dst_port: [u8; 2],
    length: [u8; 2],
    checksum: [u8; 2],
}

struct UdpPacket {
    header: Ref<Bytes, UdpHeader>,
    body: Bytes,
}

impl UdpPacket {
    fn parse(bytes: Bytes) -> Option<UdpPacket> {
        let (header, body) = Ref::new_from_prefix(bytes)?;
        Some(UdpPacket { header, body })
    }
}
joshlf commented 2 weeks ago

We'll have a chance to look at this issue in more detail later, but briefly off the top of my head: check out how we handle this in 0.8. The ByteSlice trait has been split up, and we've made the resulting traits unsealed so that external crates can implement them.

dignifiedquire commented 2 weeks ago

and we've made the resulting traits unsealed so that external crates can implement them.

Unfortunately that doesn't help, as the orphan rule prevents us from implementing the trait for an external type :/

matheus23 commented 2 weeks ago

It may be possible to workaround this via a newtype to experiment with this as a solution.