From 0c9bd1948ff400116e3374efc46048d3005bb5f6 Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Fri, 13 Dec 2024 10:29:14 +0100 Subject: [PATCH] Collection work Signed-off-by: Luca Fulchir --- bok-macro/src/collection.rs | 9 +++- bok-macro/src/pkgs.rs | 89 +++++++++++++++++++++++++++++---- bok-utils/src/repos/pkgs/one.rs | 2 + bok-utils/src/repos/pkgs/two.rs | 7 --- bok/src/collection.rs | 5 +- 5 files changed, 93 insertions(+), 19 deletions(-) diff --git a/bok-macro/src/collection.rs b/bok-macro/src/collection.rs index 6e70486..bf3e14e 100644 --- a/bok-macro/src/collection.rs +++ b/bok-macro/src/collection.rs @@ -67,7 +67,14 @@ pub(crate) fn collection( ::std::sync::Arc< dyn ::bok::PkgBuilder>>>, } - impl ::bok::Collection for Collection {} + impl ::bok::Collection for Collection { + fn as_any(&self) -> &dyn ::std::any::Any { + self + } + fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any { + self + } + } } .into() } diff --git a/bok-macro/src/pkgs.rs b/bok-macro/src/pkgs.rs index aef6743..99e9e8c 100644 --- a/bok-macro/src/pkgs.rs +++ b/bok-macro/src/pkgs.rs @@ -308,7 +308,7 @@ pub(crate) fn deps(attrs: TokenStream, input: TokenStream) -> TokenStream { * } #[::macro_magic::export_tokens(#pkg_builder_trait)] - pub trait #pkg_builder_trait { + pub trait #pkg_builder_trait: ::bok::Collection { #(fn #deps_builders2(&self) -> ::std::boxed::Box;) * @@ -567,9 +567,14 @@ pub(crate) fn package_impl_builder( input: TokenStream, __source_path: TokenStream, ) -> TokenStream { - let local = parse_macro_input!(input as ::syn::ItemImpl); let pkg = parse_macro_input!(attrs as ::syn::ItemStruct); + let pkg_name = pkg.ident; + let name_builder = ::quote::format_ident!("{}Builder", pkg_name); + let trait_deps = ::quote::format_ident!("BokDeps{}", pkg_name); + let trait_options = ::quote::format_ident!("BokOptions{}", pkg_name); + let trait_deps_builder = quote::format_ident!("BokBuilderDeps{}", pkg_name); + let local = parse_macro_input!(input as ::syn::ItemImpl); let local_path = &local.trait_.as_ref().unwrap().1; if local_path.segments.len() != 2 || local_path.segments[0].ident.to_string() != "bok" @@ -583,24 +588,88 @@ pub(crate) fn package_impl_builder( .to_compile_error() .into(); } - let local_funcs = local.items.iter().filter(|&it| match it { - ::syn::ImplItem::Fn(_) => true, - _ => false, + + let local_span = local.span(); + let local_funcs = local.items.into_iter().filter_map(|mut f| { + let ::syn::ImplItem::Fn(func) = &mut f else { + return None; + }; + if func.sig.ident.to_string() != "set_dependencies" { + return Some(f); + } + if func.sig.inputs.len() != 5 { + return Some(f); + } + let args = func + .sig + .inputs + .iter() + .skip(1) + .filter_map(|arg_t| { + let ::syn::FnArg::Typed(arg_repo_t) = arg_t else { + return None; + }; + let ::syn::Pat::Ident(arg_repo) = arg_repo_t.pat.as_ref() + else { + return None; + }; + Some(&arg_repo.ident) + }) + .collect::>(); + if args.len() != 4 { + return Some(f); + }; + let arg_repo = &args[0]; + let arg_build = &args[1]; + let arg_runtime = &args[2]; + let arg_test = &args[3]; + let mut proper_types: ::syn::ImplItemFn = ::syn::parse_quote! { + fn set_dependencies( + &self, + #arg_repo: ::std::sync::Arc, + #arg_build: ::bok::deps::Build, + #arg_runtime: ::bok::deps::Runtime, + #arg_test: ::bok::deps::Test, + ) -> Result<(), ()> { + let #arg_repo = { + let repo_any = #arg_repo.as_any(); + let Some(actual_repo) = repo_any.downcast_ref::() else { + return Err(()); + }; + Ok(actual_repo) + }?; + /* + let #arg_build = { + let build_any = #arg_build.0.as_any(); + let Some(actual_build) = + build_any.downcast_ref::<#trait_deps_builder>() else { + return Err(()); + }; + Ok(::bok::deps::Build(actual_build)) + }?; + */ + Ok(()) + } + }; + proper_types + .block + .stmts + .truncate(proper_types.block.stmts.len() - 1); + proper_types.block.stmts.append(&mut func.block.stmts); + func.block.stmts = proper_types.block.stmts; + + return Some(f); }); let ::syn::Fields::Named(elements) = pkg.fields else { return ::syn::Error::new( - local.span(), + local_span, "package_impl_builder: only named fields supported in base pkg", ) .to_compile_error() .into(); }; - let pkg_name = pkg.ident; - let name_builder = ::quote::format_ident!("{}Builder", pkg_name); - let trait_deps = ::quote::format_ident!("BokDeps{}", pkg_name); - let trait_options = ::quote::format_ident!("BokOptions{}", pkg_name); let non_opt_fields = elements.named.iter().filter_map(|field| { if let Some(id) = field.ident.clone() { if id.to_string() == "version" diff --git a/bok-utils/src/repos/pkgs/one.rs b/bok-utils/src/repos/pkgs/one.rs index 7959659..f4f25e6 100644 --- a/bok-utils/src/repos/pkgs/one.rs +++ b/bok-utils/src/repos/pkgs/one.rs @@ -60,11 +60,13 @@ impl ::bok::PkgBuilder for One { _runtime: ::bok::deps::Runtime, _test: ::bok::deps::Test, ) -> Result<(), ()> { + /* //TODO: automatically add repo type conversion via macro let repo_any = repo.as_any(); let Some(actual_repo) = repo_any.downcast_ref::() else { return Err(()); }; + */ Ok(()) } } diff --git a/bok-utils/src/repos/pkgs/two.rs b/bok-utils/src/repos/pkgs/two.rs index 3df8ebd..92d663e 100644 --- a/bok-utils/src/repos/pkgs/two.rs +++ b/bok-utils/src/repos/pkgs/two.rs @@ -53,13 +53,6 @@ impl ::bok::PkgBuilder for Two { _runtime: ::bok::deps::Runtime, _test: ::bok::deps::Test, ) -> Result<(), ()> { - //TODO: automatically add repo type conversion via macro - let repo_any = repo.as_any(); - let Some(actual_repo) = repo_any.downcast_ref::() else { - return Err(()); - }; - let one = actual_repo.one(); - Ok(()) } } diff --git a/bok/src/collection.rs b/bok/src/collection.rs index ec1fb8c..6a7b629 100644 --- a/bok/src/collection.rs +++ b/bok/src/collection.rs @@ -33,4 +33,7 @@ pub type PkgMap = BTreeMap, (Arc, ArcLock)>; */ -pub trait Collection {} +pub trait Collection: ::std::any::Any { + fn as_any(&self) -> &dyn ::std::any::Any; + fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any; +}