tested pkg up/downcast
Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
parent
cfd50cf8be
commit
09cef1ff93
@ -195,7 +195,7 @@ pub fn package(attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[derive(::bok::Package,::std::fmt::Debug)]
|
||||
#[derive(::bok::Package,::std::fmt::Debug, Clone)]
|
||||
#ast
|
||||
}
|
||||
.into()
|
||||
@ -238,8 +238,8 @@ pub fn impl_package(_attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
}
|
||||
};
|
||||
let version: ::syn::ImplItem = ::syn::parse_quote! {
|
||||
fn version(&self) -> &::bok::Version {
|
||||
&self.version
|
||||
fn version(&self) -> ::bok::Version {
|
||||
self.version.clone()
|
||||
}
|
||||
};
|
||||
let base: ::syn::ImplItem = ::syn::parse_quote! {
|
||||
@ -252,6 +252,16 @@ pub fn impl_package(_attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
Some(&mut self.base)
|
||||
}
|
||||
};
|
||||
let any: ::syn::ImplItem = ::syn::parse_quote! {
|
||||
fn as_any(&self) -> &dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
};
|
||||
let any_mut: ::syn::ImplItem = ::syn::parse_quote! {
|
||||
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
};
|
||||
let hash: ::syn::ImplItem = ::syn::parse_quote! {
|
||||
fn hash(&self) -> ::bok::Hash {
|
||||
use ::sha3::{Digest};
|
||||
@ -295,6 +305,8 @@ pub fn impl_package(_attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
ast.items.push(version);
|
||||
ast.items.push(base);
|
||||
ast.items.push(base_mut);
|
||||
ast.items.push(any);
|
||||
ast.items.push(any_mut);
|
||||
ast.items.push(hash);
|
||||
ast.items.push(hash_code);
|
||||
|
||||
@ -562,12 +574,6 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
}
|
||||
impl #name {
|
||||
pub fn as_any(&self) -> &dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
pub fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
pub fn as_pkg(&self) -> &dyn ::bok::Pkg {
|
||||
self
|
||||
}
|
||||
@ -598,8 +604,19 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
|
||||
}
|
||||
*/
|
||||
impl ::bok::PkgBuilder for #name_builder2 {
|
||||
type Package = #name;
|
||||
fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder<Package = #name> {
|
||||
fn name(&self) -> ::bok::PkgName {
|
||||
use ::bok::Pkg;
|
||||
#name::default().name()
|
||||
}
|
||||
fn path(&self) -> ::bok::Path<::bok::PkgName> {
|
||||
use ::bok::Pkg;
|
||||
#name::default().path()
|
||||
}
|
||||
fn version(&self) -> ::bok::Version {
|
||||
use ::bok::Pkg;
|
||||
#name::default().version()
|
||||
}
|
||||
fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder {
|
||||
let def = #name::default();
|
||||
#(if self.#non_opt_fields5.is_none() {
|
||||
self.#non_opt_fields5 = Some(def.#non_opt_fields5);
|
||||
@ -607,18 +624,18 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
|
||||
|
||||
self
|
||||
}
|
||||
fn build(&mut self) -> Result<#name, ::std::boxed::Box<dyn ::std::error::Error>> {
|
||||
fn build(&mut self) -> Result<Box<dyn ::bok::Pkg>, ::std::boxed::Box<dyn ::std::error::Error>> {
|
||||
#(if self.#non_opt_fields2.is_none() {
|
||||
return ::std::result::Result::Err("unset field".into());
|
||||
})*
|
||||
Ok(
|
||||
#name {
|
||||
Box::new(#name {
|
||||
// FIXME: user must be able to override. Trait?
|
||||
base: #base_type::default(),
|
||||
version: #name::default().version,
|
||||
#(#non_opt_fields3 : self.#non_opt_fields3.clone().unwrap(),)*
|
||||
#(#opt_fields2 : self.#opt_fields2.clone(),)*
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -629,10 +646,10 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
|
||||
pub fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
pub fn as_builder(&self) -> &dyn ::bok::PkgBuilder<Package = #name> {
|
||||
pub fn as_builder(&self) -> &dyn ::bok::PkgBuilder {
|
||||
self
|
||||
}
|
||||
pub fn as_builder_mut(&mut self) -> &mut dyn ::bok::PkgBuilder<Package = #name> {
|
||||
pub fn as_builder_mut(&mut self) -> &mut dyn ::bok::PkgBuilder {
|
||||
self
|
||||
}
|
||||
#(pub fn #non_opt_fields4 (&mut self, val : #non_opt_types2) -> &mut Self {
|
||||
|
@ -58,9 +58,12 @@ impl Pkgs2 {
|
||||
/// override the package `two` options from the base repostiory (Pkgs1)
|
||||
pub fn two(&self) -> Two {
|
||||
use ::bok::PkgBuilder;
|
||||
Two::builder()
|
||||
let pkg: Box<dyn ::bok::Pkg> = Two::builder()
|
||||
.my_attr(42)
|
||||
.build()
|
||||
.expect("Can't build package Two")
|
||||
.expect("Can't build package Two");
|
||||
|
||||
let two = pkg.as_any().downcast_ref::<Two>().unwrap();
|
||||
two.clone()
|
||||
}
|
||||
}
|
||||
|
@ -21,18 +21,19 @@ use ::std::{
|
||||
vec::Vec,
|
||||
};
|
||||
|
||||
use crate::{Path, Pkg, PkgName, RepoName, Repository};
|
||||
use crate::{Path, PkgBuilder, PkgName, RepoName, Repository};
|
||||
|
||||
#[derive(Debug, ::thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("package already present")]
|
||||
AlreadyPresent((Arc<dyn Repository>, ArcLock<dyn Pkg>)),
|
||||
AlreadyPresent((Arc<dyn Repository>, ArcLock<dyn PkgBuilder>)),
|
||||
#[error("not found")]
|
||||
NotFound,
|
||||
}
|
||||
|
||||
type ArcLock<T> = Arc<RwLock<T>>;
|
||||
type PkgMap = BTreeMap<Path<PkgName>, (Arc<dyn Repository>, ArcLock<dyn Pkg>)>;
|
||||
type PkgMap =
|
||||
BTreeMap<Path<PkgName>, (Arc<dyn Repository>, ArcLock<dyn PkgBuilder>)>;
|
||||
|
||||
/// Collection of packages, subset of what is present on one repository only
|
||||
pub struct Collection {
|
||||
@ -51,7 +52,7 @@ impl Collection {
|
||||
pub fn add_pkg(
|
||||
&self,
|
||||
r: Arc<dyn Repository>,
|
||||
p: ArcLock<dyn Pkg>,
|
||||
p: ArcLock<dyn PkgBuilder>,
|
||||
) -> Result<(), Error> {
|
||||
let repo_name = r.path();
|
||||
let mut repos = self.repos.write().unwrap();
|
||||
@ -85,7 +86,7 @@ impl Collection {
|
||||
pub fn find(
|
||||
&self,
|
||||
pkg_path: Path<PkgName>,
|
||||
) -> Result<(Arc<dyn Repository>, ArcLock<dyn Pkg>), Error> {
|
||||
) -> Result<(Arc<dyn Repository>, ArcLock<dyn PkgBuilder>), Error> {
|
||||
let repos_pkgs = self.repos_pkgs.read().unwrap();
|
||||
for (_, pkg_map) in repos_pkgs.iter() {
|
||||
match pkg_map.get(&pkg_path) {
|
||||
@ -101,7 +102,7 @@ impl Collection {
|
||||
&self,
|
||||
repo_path: Path<RepoName>,
|
||||
pkg_path: Path<PkgName>,
|
||||
) -> Result<(Arc<dyn Repository>, ArcLock<dyn Pkg>), Error> {
|
||||
) -> Result<(Arc<dyn Repository>, ArcLock<dyn PkgBuilder>), Error> {
|
||||
let repos_pkgs = self.repos_pkgs.read().unwrap();
|
||||
match repos_pkgs.get(&repo_path) {
|
||||
None => Err(Error::NotFound),
|
||||
|
@ -20,6 +20,10 @@ mod collection;
|
||||
mod names;
|
||||
pub use collection::Collection;
|
||||
pub use names::{Path, PkgName, RepoName};
|
||||
mod deps {
|
||||
pub struct Build(pub crate::Collection);
|
||||
pub struct Runtime(pub crate::Collection);
|
||||
}
|
||||
|
||||
pub use ::bok_macro::{
|
||||
impl_package, package, pkg_fn_to_code, repository, Package, Repository,
|
||||
@ -86,7 +90,7 @@ macro_rules! packages {
|
||||
}
|
||||
|
||||
/// Marks your struct as a repository
|
||||
pub trait Repository: ::std::fmt::Debug {
|
||||
pub trait Repository: ::core::fmt::Debug {
|
||||
fn name(&self) -> RepoName;
|
||||
fn path(&self) -> Path<RepoName>;
|
||||
}
|
||||
@ -114,9 +118,19 @@ pub trait Pkg:
|
||||
{
|
||||
fn name(&self) -> PkgName;
|
||||
fn path(&self) -> Path<PkgName>;
|
||||
fn version(&self) -> &Version;
|
||||
fn version(&self) -> Version;
|
||||
fn base(&self) -> ::core::option::Option<&dyn Pkg>;
|
||||
fn base_mut(&mut self) -> ::core::option::Option<&mut dyn Pkg>;
|
||||
fn as_any(&self) -> &dyn ::std::any::Any;
|
||||
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any;
|
||||
/*
|
||||
fn dependencies_set(
|
||||
&self,
|
||||
repo: Arc<dyn Repository>,
|
||||
build: &deps::Build,
|
||||
runtime: &deps::Runtime,
|
||||
) -> Result<(), ()>;
|
||||
*/
|
||||
fn prepare(&self) -> ::core::result::Result<(), ()> {
|
||||
self.base().unwrap().prepare()
|
||||
}
|
||||
@ -168,17 +182,17 @@ pub trait Pkg:
|
||||
fn hash_code(&self) -> Hash;
|
||||
}
|
||||
|
||||
pub trait PkgBuilder: ::std::any::Any {
|
||||
type Package;
|
||||
fn default_unused(
|
||||
&mut self,
|
||||
) -> &mut dyn PkgBuilder<Package = Self::Package>;
|
||||
pub trait PkgBuilder: ::core::fmt::Debug + ::std::any::Any {
|
||||
fn name(&self) -> crate::PkgName;
|
||||
fn path(&self) -> crate::Path<crate::PkgName>;
|
||||
fn version(&self) -> crate::Version;
|
||||
fn default_unused(&mut self) -> &mut dyn crate::PkgBuilder;
|
||||
fn build(
|
||||
&mut self,
|
||||
) -> Result<Self::Package, ::std::boxed::Box<dyn ::std::error::Error>>;
|
||||
) -> Result<Box<dyn Pkg>, ::std::boxed::Box<dyn ::std::error::Error>>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PkgEmpty {
|
||||
version: Version,
|
||||
}
|
||||
@ -216,8 +230,8 @@ impl Pkg for PkgEmpty {
|
||||
fn path(&self) -> Path<PkgName> {
|
||||
"::bok::Pkg::PkgEmpty".into()
|
||||
}
|
||||
fn version(&self) -> &Version {
|
||||
&self.version
|
||||
fn version(&self) -> Version {
|
||||
self.version.clone()
|
||||
}
|
||||
fn base(&self) -> Option<&dyn Pkg> {
|
||||
None
|
||||
@ -225,6 +239,12 @@ impl Pkg for PkgEmpty {
|
||||
fn base_mut(&mut self) -> Option<&mut dyn Pkg> {
|
||||
None
|
||||
}
|
||||
fn as_any(&self) -> &dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
|
||||
self
|
||||
}
|
||||
fn prepare(&self) -> ::core::result::Result<(), ()> {
|
||||
::core::result::Result::Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user