summaryrefslogtreecommitdiffstats
path: root/vendor/derive_more/src/as_ref.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/derive_more/src/as_ref.rs')
-rw-r--r--vendor/derive_more/src/as_ref.rs83
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/derive_more/src/as_ref.rs b/vendor/derive_more/src/as_ref.rs
new file mode 100644
index 000000000..4b8ba851d
--- /dev/null
+++ b/vendor/derive_more/src/as_ref.rs
@@ -0,0 +1,83 @@
+use crate::utils::{
+ add_where_clauses_for_new_ident, AttrParams, MultiFieldData, State,
+};
+use proc_macro2::{Span, TokenStream};
+use quote::quote;
+use syn::{parse::Result, DeriveInput, Ident};
+
+pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
+ let as_ref_type = &Ident::new("__AsRefT", Span::call_site());
+ let state = State::with_type_bound(
+ input,
+ trait_name,
+ quote!(::core::convert),
+ String::from("as_ref"),
+ AttrParams::ignore_and_forward(),
+ false,
+ )?;
+ let MultiFieldData {
+ fields,
+ input_type,
+ members,
+ infos,
+ trait_path,
+ impl_generics,
+ ty_generics,
+ where_clause,
+ ..
+ } = state.enabled_fields_data();
+ let sub_items: Vec<_> = infos
+ .iter()
+ .zip(members.iter())
+ .zip(fields)
+ .map(|((info, member), field)| {
+ let field_type = &field.ty;
+ if info.forward {
+ let trait_path = quote!(#trait_path<#as_ref_type>);
+ let type_where_clauses = quote! {
+ where #field_type: #trait_path
+ };
+ let new_generics = add_where_clauses_for_new_ident(
+ &input.generics,
+ &[field],
+ as_ref_type,
+ type_where_clauses,
+ false,
+ );
+ let (impl_generics, _, where_clause) = new_generics.split_for_impl();
+ let casted_trait = quote!(<#field_type as #trait_path>);
+ (
+ quote!(#casted_trait::as_ref(&#member)),
+ quote!(#impl_generics),
+ quote!(#where_clause),
+ quote!(#trait_path),
+ quote!(#as_ref_type),
+ )
+ } else {
+ (
+ quote!(&#member),
+ quote!(#impl_generics),
+ quote!(#where_clause),
+ quote!(#trait_path<#field_type>),
+ quote!(#field_type),
+ )
+ }
+ })
+ .collect();
+ let bodies = sub_items.iter().map(|i| &i.0);
+ let impl_generics = sub_items.iter().map(|i| &i.1);
+ let where_clauses = sub_items.iter().map(|i| &i.2);
+ let trait_paths = sub_items.iter().map(|i| &i.3);
+ let return_types = sub_items.iter().map(|i| &i.4);
+
+ Ok(quote! {#(
+ impl#impl_generics #trait_paths for #input_type#ty_generics
+ #where_clauses
+ {
+ #[inline]
+ fn as_ref(&self) -> &#return_types {
+ #bodies
+ }
+ }
+ )*})
+}