Skip to content

decode_bytes could produce Bytes zero-copy via Buf::copy_to_bytes #53

@iainmcgin

Description

@iainmcgin

Follow-up from PR #51.

Current behavior

In the generated merge_field arm for a bytes_fields-tagged field:

self.value = ::bytes::Bytes::from(::buffa::types::decode_bytes(buf)?);

decode_bytes allocates a Vec<u8>, set_lens it, and copy_to_slices into it. Then Bytes::from(Vec<u8>) wraps without a second copy. Net: one allocation + one memcpy per field.

What we'd want

Buf::copy_to_bytes(len) is the Buf trait's native "take N bytes as Bytes" call. For a Bytes-backed Buf, the default impl calls Bytes::split_to(len) which is zero-copy (just a refcount bump + length adjustment). For &[u8]-backed Buf, the default falls back to an allocation+copy — same as today.

So on hot paths where the decoder is already reading from a Bytes buffer, the bytes field ends up aliasing the input buffer with no copy.

Proposal

Add a decode_bytes_to_bytes<B: Buf>(buf: &mut B) -> Result<Bytes> (or make decode_bytes generic over its output type) that calls buf.copy_to_bytes(len) instead of allocating a Vec. Codegen for bytes_fields arms switches to the new function.

Ensure:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions