diff --git a/bok-macro/src/collection.rs b/bok-macro/src/collection.rs index bf3e14e..b393e89 100644 --- a/bok-macro/src/collection.rs +++ b/bok-macro/src/collection.rs @@ -60,6 +60,7 @@ pub(crate) fn collection( * #(#[::bok_macro::collection_dep(#all_deps_builder)]) * + #[derive(::core::fmt::Debug)] pub struct Collection { repo: ::std::sync::Arc<#name>, pkgs: ::std::sync::RwLock< diff --git a/bok-macro/src/pkgs.rs b/bok-macro/src/pkgs.rs index 99e9e8c..b47a13f 100644 --- a/bok-macro/src/pkgs.rs +++ b/bok-macro/src/pkgs.rs @@ -58,7 +58,7 @@ pub(crate) fn package(attrs: TokenStream, input: TokenStream) -> TokenStream { || path.segments[1].ident.to_string() != "PkgEmpty" { let repo_argument = { - let generic_id: ::syn::Path = ::syn::parse_quote!(id); + let generic_id: ::syn::Path = ::syn::parse_quote!(id); generic_id.segments.last().unwrap().arguments.clone() }; path.segments.last_mut().unwrap().arguments = repo_argument; @@ -103,7 +103,11 @@ pub(crate) fn package_path( .into(); }; let generic_struct: ::syn::ItemStruct = ::syn::parse_quote! { - pub struct test where R: ::bok::Repository + 'static {} + pub struct test + where + R: ::bok::Repository + 'static, + C: ::bok::Collection, + {} }; let (_, generics, where_clause) = generic_struct.generics.split_for_impl(); @@ -142,9 +146,15 @@ pub(crate) fn package_path( _bok_repo: ::std::marker::PhantomData }) .unwrap(); + let collection_marker = ::syn::Field::parse_named + .parse2(quote! { + _bok_collection: ::std::marker::PhantomData + }) + .unwrap(); base_fields_extra.push(pkg_version); base_fields_extra.push(base_marker); base_fields_extra.push(repo_marker); + base_fields_extra.push(collection_marker); } None => { return ::syn::Error::new( @@ -165,6 +175,7 @@ pub(crate) fn package_path( if id.to_string() == "version" || id.to_string() == "_bok_base" || id.to_string() == "_bok_repo" + || id.to_string() == "_bok_collection" { continue; } @@ -359,8 +370,16 @@ pub(crate) fn package_impl( "BokDeps{}", t_id.path.segments.last().unwrap().ident ); + let trait_deps_builder = ::quote::format_ident!( + "BokBuilderDeps{}", + t_id.path.segments.last().unwrap().ident + ); let g: ::syn::ItemImpl = ::syn::parse_quote! { - impl trait_name for #t_id where R: ::bok::Repository + #trait_deps {} + impl trait_name for #t_id + where + R: #trait_deps, + C: #trait_deps_builder, + {} }; ast.generics = g.generics; ast.self_ty = g.self_ty; @@ -638,16 +657,30 @@ pub(crate) fn package_impl_builder( }; 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 { + build_any.downcast_ref::() else { return Err(()); }; - Ok(::bok::deps::Build(actual_build)) + Ok(actual_build) + }?; + let #arg_runtime = { + let runtime_any = #arg_runtime.0.as_any(); + let Some(actual_runtime) = + runtime_any.downcast_ref::() else { + return Err(()); + }; + Ok(actual_runtime) + }?; + let #arg_test = { + let test_any = #arg_test.0.as_any(); + let Some(actual_test) = + test_any.downcast_ref::() else { + return Err(()); + }; + Ok(actual_test) }?; - */ Ok(()) } }; @@ -675,6 +708,7 @@ pub(crate) fn package_impl_builder( if id.to_string() == "version" || id.to_string() == "_bok_base" || id.to_string() == "_bok_repo" + || id.to_string() == "_bok_collection" { return None; } @@ -705,6 +739,7 @@ pub(crate) fn package_impl_builder( if id.to_string() == "version" || id.to_string() == "_bok_base" || id.to_string() == "_bok_repo" + || id.to_string() == "_bok_collection" { return None; } @@ -735,6 +770,7 @@ pub(crate) fn package_impl_builder( if id.to_string() == "version" || id.to_string() == "_bok_base" || id.to_string() == "_bok_repo" + || id.to_string() == "_bok_collection" { return None; } @@ -765,6 +801,7 @@ pub(crate) fn package_impl_builder( if id.to_string() == "version" || id.to_string() == "_bok_base" || id.to_string() == "_bok_repo" + || id.to_string() == "_bok_collection" { return None; } @@ -822,30 +859,33 @@ pub(crate) fn package_impl_builder( quote! { #[derive(::std::default::Default, ::std::fmt::Debug)] - pub struct #name_builder + pub struct #name_builder where - R: ::bok::Repository + 'static + #trait_deps, + R: 'static + #trait_deps, + C: 'static + #trait_deps_builder { _bok_repo: ::std::marker::PhantomData, + _bok_collection: ::std::marker::PhantomData, #(#non_opt_fields: ::std::option::Option<#non_opt_types>,)* #(#opt_fields: ::std::option::Option<#opt_types>,)* } #[::macro_magic::export_tokens(#full_export_path_name)] - impl ::bok::PkgBuilder for #name_builder + impl ::bok::PkgBuilder for #name_builder where - R: ::bok::Repository + 'static + #trait_deps, + R: 'static + #trait_deps, + C: 'static + #trait_deps_builder, { fn name(&self) -> ::bok::PkgName { use ::bok::Pkg; - #pkg_name::::default().name() + #pkg_name::::default().name() } fn path(&self) -> ::bok::Path<::bok::PkgName> { use ::bok::Pkg; - #pkg_name::::default().path() + #pkg_name::::default().path() } fn version(&self) -> ::bok::Version { use ::bok::Pkg; - #pkg_name::::default().version() + #pkg_name::::default().version() } fn as_any(&self) -> &dyn ::std::any::Any { self @@ -854,7 +894,7 @@ pub(crate) fn package_impl_builder( self } fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder { - let def = #pkg_name::::default(); + let def = #pkg_name::::default(); #(if self.#non_opt_fields5.is_none() { self.#non_opt_fields5 = Some(def.#non_opt_fields5); })* @@ -869,7 +909,7 @@ pub(crate) fn package_impl_builder( #(if self.#non_opt_fields2.is_none() { return ::std::result::Result::Err("unset field".into()); })* - let mut pkg = ::std::boxed::Box::new(#pkg_name::::default()); + let mut pkg = ::std::boxed::Box::new(#pkg_name::::default()); #(pkg.#non_opt_fields3 = self.#non_opt_fields3.clone().unwrap();) * #(pkg.#opt_fields2 = self.#opt_fields2.clone();) @@ -879,13 +919,16 @@ pub(crate) fn package_impl_builder( #(#local_funcs) * } - impl #name_builder + impl #name_builder where - R: ::bok::Repository +'static + #trait_deps, + R: 'static + #trait_deps, + C: 'static + #trait_deps_builder, { + // FIXME: difference from `::default()`? pub fn new() -> Self { Self { _bok_repo: ::std::marker::PhantomData::default(), + _bok_collection: ::std::marker::PhantomData::default(), #(#non_opt_fields6: None,)* #(#opt_fields4: None,)* } @@ -937,9 +980,10 @@ pub(crate) fn package_impl_builder( -> ::std::result::Result<(),()>;) * } - impl #trait_options for #name_builder + impl #trait_options for #name_builder where - R: ::bok::Repository +'static + #trait_deps, + R: 'static + #trait_deps, + C: 'static + #trait_deps_builder, { #(fn #non_opt_fields8 (&mut self, val : #non_opt_types4) -> ::std::result::Result<(),()> { @@ -1044,10 +1088,13 @@ pub(crate) fn package_impl_base_add( } let trait_deps = ::quote::format_ident!("BokDeps{}", name_pkg); + let trait_deps_builder = + ::quote::format_ident!("BokBuilderDeps{}", name_pkg); let generic_struct: ::syn::ItemImpl = ::syn::parse_quote! { - impl test for #name_pkg + impl test for #name_pkg where - R: ::bok::Repository + 'static + #trait_deps, + R: 'static + #trait_deps, + C: 'static + #trait_deps_builder, {} }; @@ -1156,21 +1203,24 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { } let trait_deps = ::quote::format_ident!("BokDeps{}", name); + let trait_deps_builder = ::quote::format_ident!("BokBuilderDeps{}", name); let expanded = quote! { - impl ::core::fmt::Display for #name + impl ::core::fmt::Display for #name where - R: ::bok::Repository + #trait_deps, + R: #trait_deps, + C: #trait_deps_builder, { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) ->::core::fmt::Result { - <#name as ::bok::PkgCode>::fmt(self, f) + <#name as ::bok::PkgCode>::fmt(self, f) } } - impl ::bok::PkgCode for #name + impl ::bok::PkgCode for #name where - R: ::bok::Repository + 'static + #trait_deps, + R: 'static + #trait_deps, + C: 'static + #trait_deps_builder, { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) ->::core::fmt::Result @@ -1231,9 +1281,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { f.write_str(&formatted) } } - impl #name + impl #name where - R: ::bok::Repository + 'static + #trait_deps + ::core::default::Default, + R: 'static + #trait_deps + ::core::default::Default, + C: 'static + #trait_deps_builder, { pub fn as_any(&self) -> &dyn ::std::any::Any { self diff --git a/bok-macro/src/repos.rs b/bok-macro/src/repos.rs index f158e4a..d9c7942 100644 --- a/bok-macro/src/repos.rs +++ b/bok-macro/src/repos.rs @@ -279,7 +279,7 @@ pub(crate) fn repo_packages( // "#[repo_packages(my::pkg)]" -->> "#[repo_packages(my::pkg)])" let mut rewrite = false; let repo_argument = { - let generic_id: ::syn::Path = ::syn::parse_quote!(id); + let generic_id: ::syn::Path = ::syn::parse_quote!(id); generic_id.segments.last().unwrap().arguments.clone() }; for p in packages.0.iter_mut() { diff --git a/bok-utils/src/main.rs b/bok-utils/src/main.rs index fedb1d5..695cd3b 100644 --- a/bok-utils/src/main.rs +++ b/bok-utils/src/main.rs @@ -16,6 +16,7 @@ */ mod conf; +//mod expanded; mod repos; fn main() { diff --git a/bok-utils/src/repos/pkgs/one.rs b/bok-utils/src/repos/pkgs/one.rs index f4f25e6..d9f8df4 100644 --- a/bok-utils/src/repos/pkgs/one.rs +++ b/bok-utils/src/repos/pkgs/one.rs @@ -32,6 +32,7 @@ impl ::std::default::Default for One { One { _bok_base: ::std::marker::PhantomData::default(), _bok_repo: ::std::marker::PhantomData::default(), + _bok_collection: ::std::marker::PhantomData::default(), my_attr: 1, version: ::bok::Version { major: 0, diff --git a/bok-utils/src/repos/pkgs/three.rs b/bok-utils/src/repos/pkgs/three.rs index 57a0f1f..217790f 100644 --- a/bok-utils/src/repos/pkgs/three.rs +++ b/bok-utils/src/repos/pkgs/three.rs @@ -22,14 +22,13 @@ pub struct Three { pub my_attr: u32, } -impl ::std::default::Default for Three -where - R: ::bok::Repository, -{ +#[::bok::package_impl] +impl ::std::default::Default for Three { fn default() -> Self { Three { _bok_base: ::std::marker::PhantomData::default(), _bok_repo: ::std::marker::PhantomData::default(), + _bok_collection: ::std::marker::PhantomData::default(), version: ::bok::Version { major: 0, minor: 0, diff --git a/bok-utils/src/repos/pkgs/two.rs b/bok-utils/src/repos/pkgs/two.rs index 92d663e..5e9cd6c 100644 --- a/bok-utils/src/repos/pkgs/two.rs +++ b/bok-utils/src/repos/pkgs/two.rs @@ -28,6 +28,7 @@ impl ::std::default::Default for Two { Two { _bok_base: ::std::marker::PhantomData::default(), _bok_repo: ::std::marker::PhantomData::default(), + _bok_collection: ::std::marker::PhantomData::default(), my_attr: 2, my_attr2: 2, version: ::bok::Version { diff --git a/bok/src/collection.rs b/bok/src/collection.rs index 6a7b629..2b4690c 100644 --- a/bok/src/collection.rs +++ b/bok/src/collection.rs @@ -33,7 +33,7 @@ pub type PkgMap = BTreeMap, (Arc, ArcLock)>; */ -pub trait Collection: ::std::any::Any { +pub trait Collection: ::std::any::Any + ::core::fmt::Debug { fn as_any(&self) -> &dyn ::std::any::Any; fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any; }