Add buffa-remote-derive: ProtoString/ProtoBytes/ProtoList/ProtoBox/MapStorage for remote types#251
Open
rsd-darshan wants to merge 2 commits into
Open
Add buffa-remote-derive: ProtoString/ProtoBytes/ProtoList/ProtoBox/MapStorage for remote types#251rsd-darshan wants to merge 2 commits into
rsd-darshan wants to merge 2 commits into
Conversation
…types Generates the newtype + Deref/AsRef/From/buffa-trait boilerplate that the orphan rule otherwise forces consumers to hand-write when wrapping a foreign type (e.g. ecow::EcoString) to satisfy a pluggable owned-type trait. ProtoBox and MapStorage are out of scope here: their reference newtypes call inherent methods (smallbox::SmallBox::into_inner, indexmap::IndexMap::insert) rather than trait methods, so covering them needs a different, attribute-driven design and will ship as a follow-up.
|
All contributors have signed the CLA ✍️ ✅ |
These two call inherent methods on the remote type (smallbox::SmallBox:: into_inner, indexmap::IndexMap::insert) rather than trait methods, so unlike ProtoString/ProtoBytes/ProtoList they can't be synthesized purely from supertrait bounds. Default to the conventional method names (new/into_inner for pointers, len/insert/clear/iter for maps) with an attribute override for remote types that name them differently. Also renames RemoteField::remote_ty to field_ty, since it always holds the wrapped field's actual type rather than the (documentation-only) attribute value -- the old name was misleading about what's actually used for codegen.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #212 — a
#[derive(...)] #[buffa(remote = ...)]macro that generates the newtype boilerplate (Deref,AsRef/DerefMut, the relevantFromimpls, and the buffa trait itself) needed to use a foreign type as a custom owned field type.Two tiers, one crate
ProtoString,ProtoBytes,ProtoList— the remote type's existing supertrait bounds (From<&str>,From<Vec<u8>>,FromIterator<T>, etc.) give the macro everything it needs; no extra configuration beyond naming the remote type.ProtoBox,MapStorage— their reference newtypes (examples/custom-types/src/types/small_box.rs,index_map.rs) call inherent methods on the remote type (smallbox::SmallBox::into_inner(),indexmap::IndexMap::insert()), not trait methods, so the macro can't synthesize the call purely from bounds. These default to the conventional method names (new/into_innerfor pointers;len/insert/clear/iterfor maps) with an attribute override for a remote type that names them differently:The override and the default are both rendered as UFCS-style calls (
Type::method(&mut self.0, args...)), so a differently-named method with the same receiver shape drops in directly.Notes
#[buffa(remote = ...)]attribute is documentation, not codegen input — the macro always reads the field's actual type. Comparing the attribute's value against the field's type isn't possible from within a derive macro without resolvinguseimports, so the attribute is required (and must parse as a type, catching typos) but isn't checked for equality against the field.ProtoList's generatedclearreinitializes viaDefault::default()rather than retaining capacity — documented trade-off, acceptable per the trait's "where the underlying type allows" contract.MapStorage'sDefault/FromIteratorare required by the message codec, not by this derive (a derived impl would wrongly forceK: Default/V: Default) — must be hand-written, same reasoning asProtoList.Testing
Integration tests against real foreign types (
ecow::EcoString,smallvec::SmallVec,smallbox::SmallBox,indexmap::IndexMap, plus hand-rolled types with non-conventional method names to exercise the override paths), covering both tuple-struct and named-field newtype shapes, decode/encode round-trips, and generic element types withoutEq/Ord.task lintandtask testpass clean across the workspace.