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)])
|
#(#[::bok_macro::collection_dep(#all_deps_builder)])
|
||||||
*
|
*
|
||||||
|
#[derive(::core::fmt::Debug)]
|
||||||
pub struct Collection {
|
pub struct Collection {
|
||||||
repo: ::std::sync::Arc<#name>,
|
repo: ::std::sync::Arc<#name>,
|
||||||
pkgs: ::std::sync::RwLock<
|
pkgs: ::std::sync::RwLock<
|
||||||
|
@ -58,7 +58,7 @@ pub(crate) fn package(attrs: TokenStream, input: TokenStream) -> TokenStream {
|
|||||||
|| path.segments[1].ident.to_string() != "PkgEmpty"
|
|| path.segments[1].ident.to_string() != "PkgEmpty"
|
||||||
{
|
{
|
||||||
let repo_argument = {
|
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()
|
generic_id.segments.last().unwrap().arguments.clone()
|
||||||
};
|
};
|
||||||
path.segments.last_mut().unwrap().arguments = repo_argument;
|
path.segments.last_mut().unwrap().arguments = repo_argument;
|
||||||
@ -103,7 +103,11 @@ pub(crate) fn package_path(
|
|||||||
.into();
|
.into();
|
||||||
};
|
};
|
||||||
let generic_struct: ::syn::ItemStruct = ::syn::parse_quote! {
|
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();
|
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>
|
_bok_repo: ::std::marker::PhantomData<R>
|
||||||
})
|
})
|
||||||
.unwrap();
|
.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(pkg_version);
|
||||||
base_fields_extra.push(base_marker);
|
base_fields_extra.push(base_marker);
|
||||||
base_fields_extra.push(repo_marker);
|
base_fields_extra.push(repo_marker);
|
||||||
|
base_fields_extra.push(collection_marker);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
return ::syn::Error::new(
|
return ::syn::Error::new(
|
||||||
@ -165,6 +175,7 @@ pub(crate) fn package_path(
|
|||||||
if id.to_string() == "version"
|
if id.to_string() == "version"
|
||||||
|| id.to_string() == "_bok_base"
|
|| id.to_string() == "_bok_base"
|
||||||
|| id.to_string() == "_bok_repo"
|
|| id.to_string() == "_bok_repo"
|
||||||
|
|| id.to_string() == "_bok_collection"
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -359,8 +370,16 @@ pub(crate) fn package_impl(
|
|||||||
"BokDeps{}",
|
"BokDeps{}",
|
||||||
t_id.path.segments.last().unwrap().ident
|
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! {
|
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.generics = g.generics;
|
||||||
ast.self_ty = g.self_ty;
|
ast.self_ty = g.self_ty;
|
||||||
@ -638,16 +657,30 @@ pub(crate) fn package_impl_builder(
|
|||||||
};
|
};
|
||||||
Ok(actual_repo)
|
Ok(actual_repo)
|
||||||
}?;
|
}?;
|
||||||
/*
|
|
||||||
let #arg_build = {
|
let #arg_build = {
|
||||||
let build_any = #arg_build.0.as_any();
|
let build_any = #arg_build.0.as_any();
|
||||||
let Some(actual_build) =
|
let Some(actual_build) =
|
||||||
build_any.downcast_ref::<#trait_deps_builder>() else {
|
build_any.downcast_ref::<C>() else {
|
||||||
return Err(());
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -675,6 +708,7 @@ pub(crate) fn package_impl_builder(
|
|||||||
if id.to_string() == "version"
|
if id.to_string() == "version"
|
||||||
|| id.to_string() == "_bok_base"
|
|| id.to_string() == "_bok_base"
|
||||||
|| id.to_string() == "_bok_repo"
|
|| id.to_string() == "_bok_repo"
|
||||||
|
|| id.to_string() == "_bok_collection"
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -705,6 +739,7 @@ pub(crate) fn package_impl_builder(
|
|||||||
if id.to_string() == "version"
|
if id.to_string() == "version"
|
||||||
|| id.to_string() == "_bok_base"
|
|| id.to_string() == "_bok_base"
|
||||||
|| id.to_string() == "_bok_repo"
|
|| id.to_string() == "_bok_repo"
|
||||||
|
|| id.to_string() == "_bok_collection"
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -735,6 +770,7 @@ pub(crate) fn package_impl_builder(
|
|||||||
if id.to_string() == "version"
|
if id.to_string() == "version"
|
||||||
|| id.to_string() == "_bok_base"
|
|| id.to_string() == "_bok_base"
|
||||||
|| id.to_string() == "_bok_repo"
|
|| id.to_string() == "_bok_repo"
|
||||||
|
|| id.to_string() == "_bok_collection"
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -765,6 +801,7 @@ pub(crate) fn package_impl_builder(
|
|||||||
if id.to_string() == "version"
|
if id.to_string() == "version"
|
||||||
|| id.to_string() == "_bok_base"
|
|| id.to_string() == "_bok_base"
|
||||||
|| id.to_string() == "_bok_repo"
|
|| id.to_string() == "_bok_repo"
|
||||||
|
|| id.to_string() == "_bok_collection"
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -822,30 +859,33 @@ pub(crate) fn package_impl_builder(
|
|||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[derive(::std::default::Default, ::std::fmt::Debug)]
|
#[derive(::std::default::Default, ::std::fmt::Debug)]
|
||||||
pub struct #name_builder<R>
|
pub struct #name_builder<R, C>
|
||||||
where
|
where
|
||||||
R: ::bok::Repository + 'static + #trait_deps,
|
R: 'static + #trait_deps,
|
||||||
|
C: 'static + #trait_deps_builder
|
||||||
{
|
{
|
||||||
_bok_repo: ::std::marker::PhantomData<R>,
|
_bok_repo: ::std::marker::PhantomData<R>,
|
||||||
|
_bok_collection: ::std::marker::PhantomData<C>,
|
||||||
#(#non_opt_fields: ::std::option::Option<#non_opt_types>,)*
|
#(#non_opt_fields: ::std::option::Option<#non_opt_types>,)*
|
||||||
#(#opt_fields: ::std::option::Option<#opt_types>,)*
|
#(#opt_fields: ::std::option::Option<#opt_types>,)*
|
||||||
}
|
}
|
||||||
#[::macro_magic::export_tokens(#full_export_path_name)]
|
#[::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
|
where
|
||||||
R: ::bok::Repository + 'static + #trait_deps,
|
R: 'static + #trait_deps,
|
||||||
|
C: 'static + #trait_deps_builder,
|
||||||
{
|
{
|
||||||
fn name(&self) -> ::bok::PkgName {
|
fn name(&self) -> ::bok::PkgName {
|
||||||
use ::bok::Pkg;
|
use ::bok::Pkg;
|
||||||
#pkg_name::<R>::default().name()
|
#pkg_name::<R,C>::default().name()
|
||||||
}
|
}
|
||||||
fn path(&self) -> ::bok::Path<::bok::PkgName> {
|
fn path(&self) -> ::bok::Path<::bok::PkgName> {
|
||||||
use ::bok::Pkg;
|
use ::bok::Pkg;
|
||||||
#pkg_name::<R>::default().path()
|
#pkg_name::<R,C>::default().path()
|
||||||
}
|
}
|
||||||
fn version(&self) -> ::bok::Version {
|
fn version(&self) -> ::bok::Version {
|
||||||
use ::bok::Pkg;
|
use ::bok::Pkg;
|
||||||
#pkg_name::<R>::default().version()
|
#pkg_name::<R,C>::default().version()
|
||||||
}
|
}
|
||||||
fn as_any(&self) -> &dyn ::std::any::Any {
|
fn as_any(&self) -> &dyn ::std::any::Any {
|
||||||
self
|
self
|
||||||
@ -854,7 +894,7 @@ pub(crate) fn package_impl_builder(
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder {
|
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() {
|
#(if self.#non_opt_fields5.is_none() {
|
||||||
self.#non_opt_fields5 = Some(def.#non_opt_fields5);
|
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() {
|
#(if self.#non_opt_fields2.is_none() {
|
||||||
return ::std::result::Result::Err("unset field".into());
|
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.#non_opt_fields3 = self.#non_opt_fields3.clone().unwrap();)
|
||||||
*
|
*
|
||||||
#(pkg.#opt_fields2 = self.#opt_fields2.clone();)
|
#(pkg.#opt_fields2 = self.#opt_fields2.clone();)
|
||||||
@ -879,13 +919,16 @@ pub(crate) fn package_impl_builder(
|
|||||||
#(#local_funcs)
|
#(#local_funcs)
|
||||||
*
|
*
|
||||||
}
|
}
|
||||||
impl<R> #name_builder<R>
|
impl<R, C> #name_builder<R, C>
|
||||||
where
|
where
|
||||||
R: ::bok::Repository +'static + #trait_deps,
|
R: 'static + #trait_deps,
|
||||||
|
C: 'static + #trait_deps_builder,
|
||||||
{
|
{
|
||||||
|
// FIXME: difference from `::default()`?
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
_bok_repo: ::std::marker::PhantomData::default(),
|
_bok_repo: ::std::marker::PhantomData::default(),
|
||||||
|
_bok_collection: ::std::marker::PhantomData::default(),
|
||||||
#(#non_opt_fields6: None,)*
|
#(#non_opt_fields6: None,)*
|
||||||
#(#opt_fields4: None,)*
|
#(#opt_fields4: None,)*
|
||||||
}
|
}
|
||||||
@ -937,9 +980,10 @@ pub(crate) fn package_impl_builder(
|
|||||||
-> ::std::result::Result<(),()>;)
|
-> ::std::result::Result<(),()>;)
|
||||||
*
|
*
|
||||||
}
|
}
|
||||||
impl<R> #trait_options for #name_builder<R>
|
impl<R, C> #trait_options for #name_builder<R, C>
|
||||||
where
|
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)
|
#(fn #non_opt_fields8 (&mut self, val : #non_opt_types4)
|
||||||
-> ::std::result::Result<(),()> {
|
-> ::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 = ::quote::format_ident!("BokDeps{}", name_pkg);
|
||||||
|
let trait_deps_builder =
|
||||||
|
::quote::format_ident!("BokBuilderDeps{}", name_pkg);
|
||||||
let generic_struct: ::syn::ItemImpl = ::syn::parse_quote! {
|
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
|
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 = ::quote::format_ident!("BokDeps{}", name);
|
||||||
|
let trait_deps_builder = ::quote::format_ident!("BokBuilderDeps{}", name);
|
||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
impl<R> ::core::fmt::Display for #name<R>
|
impl<R, C> ::core::fmt::Display for #name<R, C>
|
||||||
where
|
where
|
||||||
R: ::bok::Repository + #trait_deps,
|
R: #trait_deps,
|
||||||
|
C: #trait_deps_builder,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
|
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
|
||||||
->::core::fmt::Result
|
->::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
|
where
|
||||||
R: ::bok::Repository + 'static + #trait_deps,
|
R: 'static + #trait_deps,
|
||||||
|
C: 'static + #trait_deps_builder,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
|
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
|
||||||
->::core::fmt::Result
|
->::core::fmt::Result
|
||||||
@ -1231,9 +1281,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
|
|||||||
f.write_str(&formatted)
|
f.write_str(&formatted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<R> #name<R>
|
impl<R, C> #name<R, C>
|
||||||
where
|
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 {
|
pub fn as_any(&self) -> &dyn ::std::any::Any {
|
||||||
self
|
self
|
||||||
|
@ -279,7 +279,7 @@ pub(crate) fn repo_packages(
|
|||||||
// "#[repo_packages(my::pkg)]" -->> "#[repo_packages(my::pkg<Self>)])"
|
// "#[repo_packages(my::pkg)]" -->> "#[repo_packages(my::pkg<Self>)])"
|
||||||
let mut rewrite = false;
|
let mut rewrite = false;
|
||||||
let repo_argument = {
|
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()
|
generic_id.segments.last().unwrap().arguments.clone()
|
||||||
};
|
};
|
||||||
for p in packages.0.iter_mut() {
|
for p in packages.0.iter_mut() {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
mod conf;
|
mod conf;
|
||||||
|
//mod expanded;
|
||||||
mod repos;
|
mod repos;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -32,6 +32,7 @@ impl ::std::default::Default for One {
|
|||||||
One {
|
One {
|
||||||
_bok_base: ::std::marker::PhantomData::default(),
|
_bok_base: ::std::marker::PhantomData::default(),
|
||||||
_bok_repo: ::std::marker::PhantomData::default(),
|
_bok_repo: ::std::marker::PhantomData::default(),
|
||||||
|
_bok_collection: ::std::marker::PhantomData::default(),
|
||||||
my_attr: 1,
|
my_attr: 1,
|
||||||
version: ::bok::Version {
|
version: ::bok::Version {
|
||||||
major: 0,
|
major: 0,
|
||||||
|
@ -22,14 +22,13 @@ pub struct Three {
|
|||||||
pub my_attr: u32,
|
pub my_attr: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> ::std::default::Default for Three<R>
|
#[::bok::package_impl]
|
||||||
where
|
impl ::std::default::Default for Three {
|
||||||
R: ::bok::Repository,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Three {
|
Three {
|
||||||
_bok_base: ::std::marker::PhantomData::default(),
|
_bok_base: ::std::marker::PhantomData::default(),
|
||||||
_bok_repo: ::std::marker::PhantomData::default(),
|
_bok_repo: ::std::marker::PhantomData::default(),
|
||||||
|
_bok_collection: ::std::marker::PhantomData::default(),
|
||||||
version: ::bok::Version {
|
version: ::bok::Version {
|
||||||
major: 0,
|
major: 0,
|
||||||
minor: 0,
|
minor: 0,
|
||||||
|
@ -28,6 +28,7 @@ impl ::std::default::Default for Two {
|
|||||||
Two {
|
Two {
|
||||||
_bok_base: ::std::marker::PhantomData::default(),
|
_bok_base: ::std::marker::PhantomData::default(),
|
||||||
_bok_repo: ::std::marker::PhantomData::default(),
|
_bok_repo: ::std::marker::PhantomData::default(),
|
||||||
|
_bok_collection: ::std::marker::PhantomData::default(),
|
||||||
my_attr: 2,
|
my_attr: 2,
|
||||||
my_attr2: 2,
|
my_attr2: 2,
|
||||||
version: ::bok::Version {
|
version: ::bok::Version {
|
||||||
|
@ -33,7 +33,7 @@ pub type PkgMap =
|
|||||||
BTreeMap<Path<PkgName>, (Arc<dyn Repository>, ArcLock<dyn PkgBuilder>)>;
|
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(&self) -> &dyn ::std::any::Any;
|
||||||
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any;
|
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user