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