#[derive(ReadXDR)]
{
// Attributes available to this derive:
#[xdr]
#[xdrs]
}
Expand description
Derives the ReadXDR trait for a struct or enum.
This macro generates an implementation that deserializes the type from XDR
format. All field types must implement ReadXDR.
§Attributes
#[xdr(from_type = "Type")]- Deserialize to the intermediate type “Type” before converting into the target type viaInto.#[xdr(via = "Type")]- Same as above (also impliesinto_type).#[xdr(default_variant)]- On an enum variant (which must be the trailing variant): mark it as the union’s default arm. Discriminants that match no other variant decode to this variant, with the wire discriminant stored in its first field (which must bei32). Without a default variant, unknown discriminants fail with a decode error.#[xdr(crate = "path::to::xdrs")]- Override the path to thexdrscrate (useful when re-exporting from another crate).
§Limitations
- No recursive types. XDR decoding is not self-describing; a recursive
type will loop at runtime. The macro does not detect or reject recursion.
In particular,
#[xdr(from_type = "Self")]is an infinite loop — the generated impl reads aSelfand converts it intoSelf(a no-op), re-entering the same decoder until the stack overflows. The surrogate type must always be a distinct, non-recursive type. - All field types must be deserializable. Every field (or the surrogate
type, when using
from_type/via) must independently satisfyReadXDR. The macro copies the input type’s generic bounds verbatim — it does not infer or propagate trait bounds required by a surrogate type’s own generic parameters. For example,#[xdr(from_type = "VecM<T, 8>")]on a genericWrapper<T>will not automatically addT: ReadXDR; you must supply the bound yourself. - Borrowed fields need a general lifetime implementation. A custom
field type
Borrowed<'a>must implementReadXDR<'r>whenever'r: 'a, just like the built-in borrowed types. Implementing onlyReadXDR<'a> for Borrowed<'a>does not suffice for in-place decoding: the field’s type is fixed behind a mutable pointer, so the compiler cannot shorten the returned value’s lifetime at the assignment site. Useimpl<'r: 'a, 'a> ReadXDR<'r> for Borrowed<'a>. - The lifetime name
'_ris reserved. The generatedReadXDRimpl uses'_ras its reader lifetime. A type derivingReadXDRmust not declare a generic lifetime parameter with that same name; choose another name for user-defined lifetimes.