pub trait ProtoString:
Clone
+ PartialEq
+ Default
+ Debug
+ Send
+ Sync
+ Deref<Target = str>
+ AsRef<str>
+ From<String>
+ for<'a> From<&'a str> {
// 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 string
field.
buffa implements it for the default String. Select another representation
with buffa_build’s string_type / string_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 (and buffa-smolstr in the same repository for a self-contained
smol_str newtype).
The bounds are exactly what generated code requires of a string 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 aString-specificclear, since a substituted type may be immutable).Send + Sync— so a message owning such a field staysSend + Sync; without this bound an exotic string type could silently make every containing message thread-unsafe.Deref<Target = str>andAsRef<str>— generated code borrows the field as&strby plain reference coercion (&self.fieldwhereencode_string/string_encoded_lenexpect&str), so the representation mustDereftostr;AsRef<str>is also required for the call sites that ask for it explicitly.From<String>andFrom<&str>— used by the JSON, text-format, and view→owned paths to construct the field from freshly decoded text (binary decode usesfrom_wireinstead).
For the default String 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 string — 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<String>/From<&str>— binary decode usesfrom_wirewhile JSON / text / view→owned useFrom, so a representation must not transform the text (e.g. case-fold) in one path but not the other.
§Limitations
These apply to a custom type used as a repeated element or in a map slot
(map<string, V> key, map<K, string> value). Singular / optional / oneof
uses have none of them and work with a foreign type directly. See the user
guide’s “String and bytes field representations” section for the full table.
- Must be crate-local. A custom type in a
repeatedelement ormapslot needs codegen-emittedReflectElement/ReflectMapKeyimpls (for vtable reflection), which the orphan rule permits only when the type is local to the generating crate. A foreign custom type in those positions fails to compile — wrap it in a crate-local newtype. - JSON needs native
serde. A custom string used as arepeatedelement or in amapserializes through its ownserde, so it must deriveSerialize/Deserialize(and, for an external type, enable itsserdefeature). Singular / optional / oneof custom strings use theproto_stringwith-module and need noserdeimpl. - A
mapkey needsHash + Eq(default /HashMapcontainer) orOrd(map_type(BTreeMap)); the bound is enforced at the generated field type. - No
Arbitraryimpl required, except in amap. Under thearbitraryfeature, singular / optional /repeatedfields get a generic builder, so a custom type needs no nativearbitrary::Arbitraryimpl. Themaparbitrary path currently has no per-key shim, so a custom string used as amapkey or value must deriveArbitraryitself.
Required Methods§
Sourcefn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>
fn from_wire(payload: WirePayload<'_>) -> Result<Self, DecodeError>
Construct the representation from a decoded string field’s wire payload.
This is the decode constructor: it owns the validation/ownership choice,
so a representation can borrow-and-inline a short string (no transient
heap allocation) or validate UTF-8 only when it must. Validate-and-borrow
with WirePayload::to_str (which uses buffa’s UTF-8 validator and so
picks up the fast-utf8 feature), or read raw bytes with
WirePayload::as_slice. There is
intentionally no blanket impl — every representation provides its own
optimal from_wire; the From<String>/From<&str> supertraits remain
for the JSON, text, and view→owned paths.
§Errors
Returns DecodeError::InvalidUtf8 if the payload is not valid UTF-8. A
representation that enforces additional invariants 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".