Collection: cast to concrete type
Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
parent
0c9bd1948f
commit
7beea1a36b
@ -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<
|
||||
|
@ -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<R>);
|
||||
let generic_id: ::syn::Path = ::syn::parse_quote!(id<R, C>);
|
||||
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<R> where R: ::bok::Repository + 'static {}
|
||||
pub struct test<R, C>
|
||||
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<R>
|
||||
})
|
||||
.unwrap();
|
||||
let collection_marker = ::syn::Field::parse_named
|
||||
.parse2(quote! {
|
||||
_bok_collection: ::std::marker::PhantomData<C>
|
||||
})
|
||||
.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<R> trait_name for #t_id<R> where R: ::bok::Repository + #trait_deps {}
|
||||
impl<R, C> trait_name for #t_id<R, C>
|
||||
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::<C>() 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::<C>() 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::<C>() 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<R>
|
||||
pub struct #name_builder<R, C>
|
||||
where
|
||||
R: ::bok::Repository + 'static + #trait_deps,
|
||||
R: 'static + #trait_deps,
|
||||
C: 'static + #trait_deps_builder
|
||||
{
|
||||
_bok_repo: ::std::marker::PhantomData<R>,
|
||||
_bok_collection: ::std::marker::PhantomData<C>,
|
||||
#(#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<R> ::bok::PkgBuilder for #name_builder<R>
|
||||
impl<R, C> ::bok::PkgBuilder for #name_builder<R, C>
|
||||
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::<R>::default().name()
|
||||
#pkg_name::<R,C>::default().name()
|
||||
}
|
||||
fn path(&self) -> ::bok::Path<::bok::PkgName> {
|
||||
use ::bok::Pkg;
|
||||
#pkg_name::<R>::default().path()
|
||||
#pkg_name::<R,C>::default().path()
|
||||
}
|
||||
fn version(&self) -> ::bok::Version {
|
||||
use ::bok::Pkg;
|
||||
#pkg_name::<R>::default().version()
|
||||
#pkg_name::<R,C>::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::<R>::default();
|
||||
let def = #pkg_name::<R,C>::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::<R>::default());
|
||||
let mut pkg = ::std::boxed::Box::new(#pkg_name::<R,C>::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<R> #name_builder<R>
|
||||
impl<R, C> #name_builder<R, C>
|
||||
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<R> #trait_options for #name_builder<R>
|
||||
impl<R, C> #trait_options for #name_builder<R, C>
|
||||
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<R> test for #name_pkg <R>
|
||||
impl<R, C> test for #name_pkg<R, C>
|
||||
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<R> ::core::fmt::Display for #name<R>
|
||||
impl<R, C> ::core::fmt::Display for #name<R, C>
|
||||
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<R> as ::bok::PkgCode>::fmt(self, f)
|
||||
<#name<R, C> as ::bok::PkgCode>::fmt(self, f)
|
||||
}
|
||||
}
|
||||
impl<R> ::bok::PkgCode for #name<R>
|
||||
impl<R, C> ::bok::PkgCode for #name<R, C>
|
||||
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<R> #name<R>
|
||||
impl<R, C> #name<R, C>
|
||||
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
|
||||
|
@ -279,7 +279,7 @@ pub(crate) fn repo_packages(
|
||||
// "#[repo_packages(my::pkg)]" -->> "#[repo_packages(my::pkg<Self>)])"
|
||||
let mut rewrite = false;
|
||||
let repo_argument = {
|
||||
let generic_id: ::syn::Path = ::syn::parse_quote!(id<Self>);
|
||||
let generic_id: ::syn::Path = ::syn::parse_quote!(id<Self, Collection>);
|
||||
generic_id.segments.last().unwrap().arguments.clone()
|
||||
};
|
||||
for p in packages.0.iter_mut() {
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
mod conf;
|
||||
//mod expanded;
|
||||
mod repos;
|
||||
|
||||
fn main() {
|
||||
|
@ -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,
|
||||
|
@ -22,14 +22,13 @@ pub struct Three {
|
||||
pub my_attr: u32,
|
||||
}
|
||||
|
||||
impl<R> ::std::default::Default for Three<R>
|
||||
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,
|
||||
|
@ -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 {
|
||||
|
@ -33,7 +33,7 @@ pub type PkgMap =
|
||||
BTreeMap<Path<PkgName>, (Arc<dyn Repository>, ArcLock<dyn PkgBuilder>)>;
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user