pipewire_wrapper_macro_impl/
derive_wrapper.rs

1use proc_macro2::{Ident, TokenStream};
2use quote::quote;
3use syn::parse::{Parse, ParseStream};
4use syn::{parse2, Field, Generics};
5
6use crate::ATTR_RAW_WRAPPER;
7
8struct WrappedStructInfo {
9    struct_ident: Ident,
10    struct_generics: Generics,
11    raw_wrapper_field: Field,
12}
13
14impl Parse for WrappedStructInfo {
15    fn parse(input: ParseStream) -> syn::Result<Self> {
16        match crate::parse_wrapped_struct_info(input, ATTR_RAW_WRAPPER) {
17            Ok((struct_ident, struct_generics, raw_wrapper_field, _)) => Ok(WrappedStructInfo {
18                struct_ident,
19                struct_generics,
20                raw_wrapper_field,
21            }),
22            Err(error) => Err(error),
23        }
24    }
25}
26
27pub fn derive_wrapper(input: TokenStream) -> TokenStream {
28    let struct_info = match parse2::<WrappedStructInfo>(input) {
29        Ok(parsed) => parsed,
30        Err(error) => return error.to_compile_error(),
31    };
32
33    let struct_ident = &struct_info.struct_ident;
34    let raw_wrapper_field_ident = &struct_info.raw_wrapper_field.ident;
35    let raw_wrapper_field_type = crate::get_field_type(&struct_info.raw_wrapper_field);
36
37    let mut struct_generics_without_default = struct_info.struct_generics.clone();
38    crate::strip_defaults_from_generics(&mut struct_generics_without_default);
39
40    let mut struct_generics_without_bounds = struct_generics_without_default.clone();
41    crate::strip_bounds_from_generics(&mut struct_generics_without_bounds);
42
43    quote!(
44        impl #struct_generics_without_default crate::wrapper::Wrapper for #struct_ident #struct_generics_without_bounds {
45            type RawWrapperType = #raw_wrapper_field_type;
46        }
47
48        impl #struct_generics_without_default AsRef<#raw_wrapper_field_type> for #struct_ident #struct_generics_without_bounds {
49            fn as_ref(&self) -> &<Self as crate::wrapper::Wrapper>::RawWrapperType {
50                use crate::wrapper::RawWrapper;
51                unsafe { self.#raw_wrapper_field_ident.as_ref() }
52            }
53        }
54
55        impl #struct_generics_without_default AsMut<#raw_wrapper_field_type> for #struct_ident #struct_generics_without_bounds {
56            fn as_mut(&mut self) -> &mut <Self as crate::wrapper::Wrapper>::RawWrapperType {
57                use crate::wrapper::RawWrapper;
58                unsafe { self.#raw_wrapper_field_ident.as_mut() }
59            }
60        }
61
62        impl #struct_generics_without_default std::ops::Deref for #struct_ident #struct_generics_without_bounds {
63            type Target = <Self as crate::wrapper::Wrapper>::RawWrapperType;
64
65            fn deref(&self) -> &Self::Target {
66                use crate::wrapper::RawWrapper;
67                unsafe { self.#raw_wrapper_field_ident.as_ref() }
68            }
69        }
70
71        impl #struct_generics_without_default std::ops::DerefMut for #struct_ident #struct_generics_without_bounds {
72            fn deref_mut(&mut self) -> &mut Self::Target {
73                use crate::wrapper::RawWrapper;
74                unsafe { self.#raw_wrapper_field_ident.as_mut() }
75            }
76        }
77    )
78}