Skip to main content

ProtoBytes

Trait ProtoBytes 

Source
pub trait ProtoBytes:
    Clone
    + PartialEq
    + Default
    + Debug
    + Send
    + Sync
    + Deref<Target = [u8]>
    + AsRef<[u8]>
    + From<Vec<u8>> {
    // Required method
    fn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>;
}
Expand description

The bound generated code places on the Rust type used for a proto bytes field.

buffa implements it for the default Vec<u8> and for bytes::Bytes (which decodes zero-copy from a Bytes-backed buffer). Select another representation with buffa_build’s bytes_type / bytes_type_custom. There is intentionally no blanket impl, and a foreign type cannot implement this trait (orphan rule) — wrap it in a local newtype that implements the trait; see examples/custom-types in the buffa repository for the canonical template.

This is the bytes-side twin of ProtoString; the bounds are exactly what generated code requires of a bytes field:

  • from_wire (the required method, below) — the binary decode constructor.
  • Clone + PartialEq + Default + Debug — for the #[derive(...)] and the hand-written Debug impl on message structs, and for clear() (which resets the field to Default rather than relying on a Vec-specific clear, since a substituted type may be immutable).
  • Send + Sync — so a message owning such a field stays Send + Sync.
  • Deref<Target = [u8]> and AsRef<[u8]> — generated code borrows the field as &[u8] by plain reference coercion (&self.field where encode_bytes / bytes_encoded_len expect &[u8]), so the representation must Deref to [u8]; AsRef<[u8]> is also required for the call sites that ask for it explicitly.
  • From<Vec<u8>> — used by the JSON and view→owned paths to construct the field from freshly decoded bytes (binary decode uses from_wire instead). Note that From<&[u8]> is deliberately not required: bytes::Bytes implements it only for &'static [u8], so requiring it would exclude Bytes itself.

For the default Vec<u8> representation every conversion is the identity, so the generic path costs nothing relative to the specialized one.

§Contract

The bounds are structural and cannot capture these invariants; an implementation must uphold them:

  • Default is the empty value — generated clear() resets to Default::default() and implicit-presence encoding skips empty values, so a non-empty Default silently drops or corrupts cleared fields.
  • Deref, AsRef, and the constructors observe the same content — encoding borrows via Deref / AsRef and the view / reflect paths read the same way; if they disagree, a value encodes differently than it reads back.
  • from_wire is value-equivalent to From<Vec<u8>> — binary decode uses from_wire while JSON / view→owned use From, so a representation must not transform the bytes in one path but not the other.

§Limitations

  • repeated elements and map<K, bytes> values must be crate-local. A custom type used as the element of a repeated field — or as a map<K, bytes> value — needs codegen-emitted ReflectElement (vtable) and base64 ProtoElemJson (JSON) impls, which the orphan rule permits only when the type is local to the generating crate. A foreign custom type in that position fails to compile — wrap it in a crate-local newtype. Singular, optional, and oneof uses work with a foreign type directly. (A custom bytes map value is honored just like the built-in bytes::Bytes; only the map<bytes, bytes> carve-out keeps Vec<u8> values.)
  • No Arbitrary impl required. Under the arbitrary feature codegen attaches a generic builder, so a custom type needs no native arbitrary::Arbitrary impl.

Required Methods§

Source

fn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>

Construct the representation from a decoded bytes field’s wire payload.

This is the decode constructor: it owns the borrow-vs-own choice. A Bytes-backed representation takes ownership via WirePayload::into_bytes, which is zero-copy only for an Owned payload — today produced only for multi-chunk sources, so a single-chunk source (including a single Bytes buffer) currently yields Borrowed and copies. For a guaranteed zero-copy bytes field use the built-in bytes::Bytes representation; single-chunk-Bytes zero-copy share for custom types is a planned additive enhancement. There is intentionally no blanket impl; the From<Vec<u8>> supertrait remains for the JSON and view→owned paths.

§Errors

The built-in representations are infallible. A representation that enforces additional invariants (e.g. a fixed length) can reject the value with DecodeError::Custom (carrying a static reason), or return any other DecodeError variant.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl ProtoBytes for Bytes

Source§

fn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>

Source§

impl ProtoBytes for Vec<u8>

Source§

fn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>

Implementors§