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-writtenDebugimpl on message structs, and forclear()(which resets the field toDefaultrather than relying on aVec-specificclear, since a substituted type may be immutable).Send + Sync— so a message owning such a field staysSend + Sync.Deref<Target = [u8]>andAsRef<[u8]>— generated code borrows the field as&[u8]by plain reference coercion (&self.fieldwhereencode_bytes/bytes_encoded_lenexpect&[u8]), so the representation mustDerefto[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 usesfrom_wireinstead). Note thatFrom<&[u8]>is deliberately not required:bytes::Bytesimplements it only for&'static [u8], so requiring it would excludeBytesitself.
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:
Defaultis the empty value — generatedclear()resets toDefault::default()and implicit-presence encoding skips empty values, so a non-emptyDefaultsilently drops or corrupts cleared fields.Deref,AsRef, and the constructors observe the same content — encoding borrows viaDeref/AsRefand the view / reflect paths read the same way; if they disagree, a value encodes differently than it reads back.from_wireis value-equivalent toFrom<Vec<u8>>— binary decode usesfrom_wirewhile JSON / view→owned useFrom, so a representation must not transform the bytes in one path but not the other.
§Limitations
repeatedelements andmap<K, bytes>values must be crate-local. A custom type used as the element of arepeatedfield — or as amap<K, bytes>value — needs codegen-emittedReflectElement(vtable) and base64ProtoElemJson(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 custombytesmap value is honored just like the built-inbytes::Bytes; only themap<bytes, bytes>carve-out keepsVec<u8>values.)- No
Arbitraryimpl required. Under thearbitraryfeature codegen attaches a generic builder, so a custom type needs no nativearbitrary::Arbitraryimpl.
Required Methods§
Sourcefn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>
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".