use proc_macro::TokenStream as TokenStream1;
use proc_macro2::TokenStream;
use proc_macro_crate::{FoundCrate, crate_name};
use quote::quote;
use syn::{ImplItem, ItemImpl, parse_quote};
pub(crate) fn context_path() -> TokenStream {
match crate_name("guinea-app") {
Ok(FoundCrate::Itself) => return quote!(crate::feature),
Ok(FoundCrate::Name(name)) => {
let ident = syn::Ident::new(&name, proc_macro2::Span::call_site());
return quote!(::#ident::feature);
}
Err(_) => {}
}
match crate_name("guinea") {
Ok(FoundCrate::Itself) => quote!(crate::feature),
Ok(FoundCrate::Name(name)) => {
let ident = syn::Ident::new(&name, proc_macro2::Span::call_site());
quote!(::#ident::feature)
}
Err(_) => quote!(::guinea::feature),
}
}
pub fn segment_impl(item: TokenStream1) -> TokenStream1 {
let mut item = syn::parse_macro_input!(item as ItemImpl);
let context = context_path();
let declares_installs = item
.items
.iter()
.any(|entry| matches!(entry, ImplItem::Type(ty) if ty.ident == "Installs"));
let declares_install = item
.items
.iter()
.any(|entry| matches!(entry, ImplItem::Fn(f) if f.sig.ident == "install"));
let gc = crate::handler::guinea_core_crate_path();
let declared: ImplItem = parse_quote! {
const DECLARED: ::core::option::Option<#gc::actor::shape::Declared> =
::core::option::Option::Some(#gc::actor::shape::Declared {
file: ::core::file!(),
line: ::core::line!(),
column: ::core::column!(),
crate_dir: ::core::env!("CARGO_MANIFEST_DIR"),
});
};
item.items.push(declared);
if declares_installs {
return quote!(#item).into();
}
item.items.push(parse_quote!(
type Installs = ();
));
if !declares_install {
item.items.push(parse_quote! {
fn install(
_ctx: &#context::FeatureInitContext,
_params: &Self::Params,
) -> #gc::__private::anyhow::Result<()> {
::std::result::Result::Ok(())
}
});
}
quote!(#item).into()
}