let data = match &input.data {
syn::Data::Struct(data) => Ok(data),
syn::Data::Enum(e) => Err(syn::Error::new(
e.enum_token.span(),
format!("`{trait_ident}` cannot be derived for enums"),
)),
syn::Data::Union(u) => Err(syn::Error::new(
u.union_token.span(),
format!("`{trait_ident}` cannot be derived for unions"),
)),
}?;
let expansions = iflet Some(attr) =
StructAttribute::parse_attrs(&input.attrs, attr_name)?
{ if data.fields.len() != 1 { return Err(syn::Error::new( if data.fields.is_empty() {
data.struct_token.span
} else {
data.fields.span()
},
format!( "`#[{attr_name}(...)]` attribute can only be placed on structs with exactly \
one field",
),
));
}
let field = data.fields.iter().next().unwrap(); if FieldAttribute::parse_attrs(&field.attrs, attr_name)?.is_some() { return Err(syn::Error::new(
field.span(),
format!("`#[{attr_name}(...)]` cannot be placed on both struct and its field"),
));
}
/// Type alias for an expansion context: /// - [`syn::Ident`] of the derived trait. /// - [`syn::Ident`] of the derived trait method. /// - Optional `mut` token indicating [`AsMut`] expansion. /// /// [`syn::Ident`]: struct@syn::Ident type ExpansionCtx<'a> = (&'a syn::Ident, &'a syn::Ident, Option<&'a Token![mut]>);
/// Expansion of a macro for generating [`AsRef`]/[`AsMut`] implementations for a single field of a /// struct. struct Expansion<'a> { /// [`ExpansionCtx`] of the derived trait.
trait_info: ExpansionCtx<'a>,
/// [`syn::Ident`] of the struct. /// /// [`syn::Ident`]: struct@syn::Ident
ident: &'a syn::Ident,
/// [`syn::Generics`] of the struct.
generics: &'a syn::Generics,
/// [`syn::Field`] of the struct.
field: &'a syn::Field,
/// Index of the [`syn::Field`].
field_index: usize,
/// Attribute specifying which conversions should be generated.
conversions: Option<attr::Conversion>,
}
impl ToTokens for Expansion<'_> { fn to_tokens(&self, tokens: &mut TokenStream) { let field_ty = &self.field.ty; let field_ident = self.field.ident.as_ref().map_or_else(
|| Either::Right(syn::Index::from(self.field_index)),
Either::Left,
);
let (trait_ident, method_ident, mut_) = &self.trait_info; let ty_ident = &self.ident;
let field_ref = quote! { & #mut_self.#field_ident };
for return_ty in return_tys { /// Kind of a generated implementation, chosen based on attribute arguments. enum ImplKind { /// Returns a reference to a field.
Direct,
/// Forwards `as_ref`/`as_mut` call on a field.
Forwarded,
/// Uses autoref-based specialization to determine whether to use direct or /// forwarded implementation, based on whether the field and the return type match. /// /// Doesn't work when generics are involved.
Specialized,
}
let body = match &impl_kind {
ImplKind::Direct => Cow::Borrowed(&field_ref),
ImplKind::Forwarded => Cow::Owned(quote! {
<#field_tyas#trait_ty>::#method_ident(#field_ref)
}),
ImplKind::Specialized => Cow::Owned(quote! { use derive_more::__private::ExtractRef as _;
let conv =
<derive_more::__private::Conv<& #mut_#field_ty, #return_ty> as derive_more::core::default::Default>::default();
(&&conv).__extract_ref(#field_ref)
}),
};
quote! { #[allow(unreachable_code)] // omit warnings for `!` and other unreachable types #[automatically_derived] impl#impl_gens#trait_tyfor#ty_ident#ty_gens#where_clause { #[inline] fn#method_ident(& #mut_self) -> & #mut_#return_ty { #body
}
}
}
.to_tokens(tokens);
}
}
}
/// Representation of an [`AsRef`]/[`AsMut`] derive macro struct container attribute. /// /// ```rust,ignore /// #[as_ref(forward)] /// #[as_ref(<types>)] /// ``` type StructAttribute = attr::Conversion;
/// Representation of an [`AsRef`]/[`AsMut`] derive macro field attribute. /// /// ```rust,ignore /// #[as_ref] /// #[as_ref(skip)] #[as_ref(ignore)] /// #[as_ref(forward)] /// #[as_ref(<types>)] /// ``` type FieldAttribute = attr::FieldConversion;
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.