Skip to main content

Module view

Module view 

Source
Expand description

Zero-copy borrowed message views.

Buffa generates two representations for each protobuf message:

  • Owned (MyMessage): uses String, Vec<u8>, Vec<T> for fields. Suitable for building messages, long-lived storage, and mutation.

  • Borrowed (MyMessageView<'a>): uses &'a str, &'a [u8], and slice-backed repeated fields. Borrows directly from the input buffer for zero-copy deserialization on the read path.

§Motivation

In a typical RPC handler, the request is parsed from a buffer, fields are read, and the buffer is discarded. With owned types, every string and bytes field requires an allocation + copy. With view types, strings and bytes borrow directly from the input buffer — no allocation at all.

This is analogous to how Cap’n Proto’s Rust implementation works, and how Go achieves zero-copy string deserialization via its garbage collector.

§Usage pattern

// Decode a view (zero-copy, borrows from `wire_bytes`)
let request = MyRequestView::decode_view(&wire_bytes)?;
println!("name: {}", request.name);  // &str, no allocation

// Build an owned response
let response = MyResponse {
    id: request.id,
    status: "ok".into(),
    ..Default::default()
};

// Convert view to owned if needed for storage
let owned: MyRequest = request.to_owned_message();

§Reborrowing from OwnedView

OwnedView<V> wraps a decoded view with the lifetime erased to 'static. Use Deref (&*owned / owned.name) for inline field reads within the same scope. Use OwnedView::reborrow when you need to assign the view to a binding, pass it to a function with a non-'static lifetime parameter, or return a borrowed field:

// reborrow ties the returned borrow to the OwnedView's lifetime.
fn handler<'a>(req: &'a OwnedView<PersonView<'static>>) -> &'a str {
    req.reborrow().name
}

Deref alone gives &PersonView<'static>, so field borrows appear 'static to the compiler — this is unsound to rely on outside the scope that holds the OwnedView. Always use reborrow when the borrow needs to outlive the current expression. See OwnedView for a full side-by-side comparison.

§Generated code shape

For a message like:

message Person {
  string name = 1;
  int32 id = 2;
  bytes avatar = 3;
  repeated string tags = 4;
  Address address = 5;
}

Buffa generates:

// Owned type (heap-allocated strings and vecs)
pub struct Person {
    pub name: String,
    pub id: i32,
    pub avatar: Vec<u8>,
    pub tags: Vec<String>,
    pub address: MessageField<Address>,
    #[doc(hidden)] pub __buffa_unknown_fields: UnknownFields,
}

// Borrowed view type (zero-copy from input buffer)
pub struct PersonView<'a> {
    pub name: &'a str,
    pub id: i32,
    pub avatar: &'a [u8],
    pub tags: RepeatedView<'a, &'a str>,
    pub address: MessageFieldView<AddressView<'a>>,
    pub __buffa_unknown_fields: UnknownFieldsView<'a>,
}

Structs§

MapView
A borrowed view of a map field.
MessageFieldView
A borrowed view of an optional message field.
OwnedView
An owned, 'static container for a decoded message view.
RepeatedView
A borrowed view of a repeated field.
UnknownFieldsView
A borrowed view of unknown fields.

Traits§

DefaultViewInstance
Provides access to a lazily-initialized default view instance.
MessageView
Trait for zero-copy borrowed message views.
ViewEncode
Serialize a MessageView directly from its borrowed fields.
ViewReborrow
Exposes the real lifetime of an OwnedView’s borrows.