From 2e75c8a8f99c617db8172c9333d0cb9f70886920 Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Fri, 6 Dec 2024 16:47:32 +0100 Subject: [PATCH] Split repos in their own modules also start working on collections Signed-off-by: Luca Fulchir --- bok-macro/src/pkgs.rs | 12 +++++++ bok-macro/src/repos.rs | 28 ++++++++++++++-- bok-utils/src/main.rs | 34 ++++++++----------- bok-utils/src/repos/mod.rs | 55 +++---------------------------- bok-utils/src/repos/pkgs/one.rs | 5 +++ bok-utils/src/repos/pkgs/two.rs | 5 +-- bok-utils/src/repos/r1/mod.rs | 44 +++++++++++++++++++++++++ bok-utils/src/repos/r2/mod.rs | 58 +++++++++++++++++++++++++++++++++ bok/src/lib.rs | 2 ++ 9 files changed, 168 insertions(+), 75 deletions(-) create mode 100644 bok-utils/src/repos/r1/mod.rs create mode 100644 bok-utils/src/repos/r2/mod.rs diff --git a/bok-macro/src/pkgs.rs b/bok-macro/src/pkgs.rs index d09911c..0dccd7f 100644 --- a/bok-macro/src/pkgs.rs +++ b/bok-macro/src/pkgs.rs @@ -257,6 +257,7 @@ pub(crate) fn deps_build( let vis = local.vis; let pkg_trait = quote::format_ident!("BokDeps{}", ident); + let pkg_builder_trait = quote::format_ident!("BokBuilderDeps{}", ident); use ::convert_case::{Case, Casing}; let deps = packages @@ -280,6 +281,11 @@ pub(crate) fn deps_build( #(fn #deps(&self) -> ::std::boxed::Box;) * } + #[::macro_magic::export_tokens(#pkg_builder_trait)] + pub trait #pkg_builder_trait { + #(fn #deps(&self) -> ::std::boxed::Box;) + * + } } .into() } @@ -988,6 +994,12 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream { use ::bok::Pkg; #name::::default().version() } + fn as_any(&self) -> &dyn ::std::any::Any { + self + } + fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any { + self + } fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder { let def = #name::::default(); #(if self.#non_opt_fields5.is_none() { diff --git a/bok-macro/src/repos.rs b/bok-macro/src/repos.rs index 25411a5..8b5fea7 100644 --- a/bok-macro/src/repos.rs +++ b/bok-macro/src/repos.rs @@ -193,14 +193,26 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream { } // holds the list of all package names, snake case let mut all_pkgs = Vec::<::syn::Ident>::with_capacity(items.fields.len()); + let mut all_deps_builder = + Vec::<::syn::Path>::with_capacity(items.fields.len()); for it in items.fields.iter() { let Some(id) = &it.ident else { continue }; let id_str = id.to_string(); - if id_str.starts_with("_p_") { - let name = id_str.strip_prefix("_p_").unwrap().to_owned(); - all_pkgs.push(::quote::format_ident!("{}", name)); + if !id_str.starts_with("_p_") { + continue; } + let ::syn::Type::Path(raw_path) = &it.ty else { + continue; + }; + let name = id_str.strip_prefix("_p_").unwrap().to_owned(); + all_pkgs.push(::quote::format_ident!("{}", name)); + + let mut dep_builder_trait = raw_path.path.clone(); + let pkg_t = &mut dep_builder_trait.segments.last_mut().unwrap(); + pkg_t.ident = ::quote::format_ident!("BokBuilderDeps{}", pkg_t.ident); + + all_deps_builder.push(dep_builder_trait); } all_pkgs.sort_by(|a, b| a.to_string().cmp(&b.to_string())); let pkgs_num: usize = all_pkgs.len(); @@ -231,6 +243,14 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream { self } } + //#[::bok_macro::collection(#(#all_deps_builder,)*)] + struct Collection { + repo: ::std::sync::Arc<#name>, + pkgs: ::std::sync::RwLock< + ::std::vec::Vec< + ::std::sync::Arc< + dyn ::bok::PkgBuilder>>>, + } }.into() } @@ -413,6 +433,8 @@ pub(crate) fn repo_impl( let reponame = &local.self_ty; quote! { + use ::bok_macro::repo_impl_methods; + use ::bok_macro::repo_impl_pkg_deps; #[::bok_macro::repo_impl_methods(#reponame)] #local } diff --git a/bok-utils/src/main.rs b/bok-utils/src/main.rs index 781ca60..6b17d07 100644 --- a/bok-utils/src/main.rs +++ b/bok-utils/src/main.rs @@ -18,32 +18,26 @@ mod conf; mod repos; -/* -trait TP { - fn p(r: &impl TR); -} -trait TR { - fn r(); -} - -struct R {} -impl TR for R { - fn r() {} -} -struct P {} -impl TP for P { - fn p(r: &impl TR) {} -} -*/ - fn main() { //let one = repos::pkgs::one::One::default(); - let pkgs1 = repos::Pkgs1::default(); - let pkgs2 = repos::Pkgs2::default(); + use ::std::sync::Arc; + let pkgs1 = Arc::new(repos::R1::default()); + let pkgs2 = Arc::new(repos::R2::default()); use ::bok::Repository; println!("pkgs1: {}", pkgs1.name()); println!("pkgs2: {}", pkgs2.name()); + let build_deps = ::bok::deps::Build(::bok::Collection::new()); + let run_deps = ::bok::deps::Runtime(::bok::Collection::new()); + + let one = pkgs1.one(); + use ::bok::Pkg; + let res = one.dependencies_set(pkgs1, &build_deps, &run_deps); + println!("{:?}", res); + + let two = pkgs2.two(); + let res = two.dependencies_set(pkgs2, &build_deps, &run_deps); + println!("{:?}", res); /* let mut pb: pkgs::one::OneBuilder = pkgs1.one(); diff --git a/bok-utils/src/repos/mod.rs b/bok-utils/src/repos/mod.rs index 6b2268d..657bad6 100644 --- a/bok-utils/src/repos/mod.rs +++ b/bok-utils/src/repos/mod.rs @@ -19,56 +19,11 @@ //! Example of two package repositories, where one //! extends ancd changes another +// all packages we have pub mod pkgs; -// FIXME: why? -use ::bok_macro::repo_impl_methods; -use ::bok_macro::repo_impl_pkg_deps; -// Export multiple packages in this module -use ::bok::repository; +pub mod r1; +pub mod r2; -/// -/// Base repository with some packages -#[::bok::repository(::bok::RepositoryEmpty)] -#[::bok::repo_packages(pkgs::one::One)] -#[derive(::std::default::Default)] -pub struct Pkgs1 { - r1: i32, -} - -#[::bok::repo_impl] -impl Pkgs1 {} - -/// -/// This repository extends and changes Pkgs1 -#[::bok::repository(Pkgs1)] -#[::bok::repo_packages(pkgs::two::Two)] -#[derive(::std::default::Default)] -pub struct Pkgs2 { - r2: i32, -} - -#[::bok::repo_impl] -impl Pkgs2 {} - -/* -impl Pkgs2 { - /// override the package `two` options from the base repostiory (Pkgs1) - pub fn two(&self) -> Two { - use ::bok::PkgBuilder; - let pkg: Box = Two::builder() - .my_attr(42) - .build() - .expect("Can't build package Two"); - - let two = pkg.as_any().downcast_ref::().unwrap(); - two.clone() - } -} - -/// This repository extends both Pkgs1 and Pkgs2 -#[::bok::repository(Pkgs2)] -#[::bok::repository(Pkgs1)] -#[derive(::std::default::Default)] -pub struct Pkgs3 {} -*/ +pub use r1::R1; +pub use r2::R2; diff --git a/bok-utils/src/repos/pkgs/one.rs b/bok-utils/src/repos/pkgs/one.rs index e775677..c580c15 100644 --- a/bok-utils/src/repos/pkgs/one.rs +++ b/bok-utils/src/repos/pkgs/one.rs @@ -52,6 +52,11 @@ impl ::bok::Pkg for One { _build: &::bok::deps::Build, _runtime: &::bok::deps::Runtime, ) -> Result<(), ()> { + //TODO: automatically add repo type conversion via macro + let repo_any = repo.as_any(); + let Some(actual_repo) = repo_any.downcast_ref::() else { + return Err(()); + }; Ok(()) } } diff --git a/bok-utils/src/repos/pkgs/two.rs b/bok-utils/src/repos/pkgs/two.rs index e59746a..0aceb18 100644 --- a/bok-utils/src/repos/pkgs/two.rs +++ b/bok-utils/src/repos/pkgs/two.rs @@ -46,14 +46,15 @@ impl ::bok::Pkg for Two { fn dependencies_set( &self, repo: ::std::sync::Arc, - _build: &::bok::deps::Build, + build: &::bok::deps::Build, _runtime: &::bok::deps::Runtime, ) -> Result<(), ()> { + //TODO: automatically add repo type conversion via macro let repo_any = repo.as_any(); let Some(actual_repo) = repo_any.downcast_ref::() else { return Err(()); }; - let _ = actual_repo.one(); + let one = actual_repo.one(); Ok(()) } diff --git a/bok-utils/src/repos/r1/mod.rs b/bok-utils/src/repos/r1/mod.rs new file mode 100644 index 0000000..554daf8 --- /dev/null +++ b/bok-utils/src/repos/r1/mod.rs @@ -0,0 +1,44 @@ +/* + * Copyright 2024 Luca Fulchir + * + * Licensed under the Apache License, Version 2.0 with LLVM exception (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License and of the exception at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * https://spdx.org/licenses/LLVM-exception.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! +//! Example of a simple repository of packages + +// get the 'pkgs' from somewhere +use crate::repos::pkgs; + +/* or you can create and export your own packages +pub mod pkgs { + pub mod one { + pub use crate::repos::pkgs::one::*; + } +} +*/ + +use ::bok::repository; + +/// +/// Base repository with some packages +#[::bok::repository(::bok::RepositoryEmpty)] +#[::bok::repo_packages(pkgs::one::One)] +#[derive(::std::default::Default)] +pub struct R1 { + r1: i32, +} + +#[::bok::repo_impl] +impl R1 {} diff --git a/bok-utils/src/repos/r2/mod.rs b/bok-utils/src/repos/r2/mod.rs new file mode 100644 index 0000000..276f3dc --- /dev/null +++ b/bok-utils/src/repos/r2/mod.rs @@ -0,0 +1,58 @@ +/* + * Copyright 2024 Luca Fulchir + * + * Licensed under the Apache License, Version 2.0 with LLVM exception (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License and of the exception at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * https://spdx.org/licenses/LLVM-exception.html + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//! +//! Example of a repository extending another +/// +/// This repository extends and changes R1 +// FIXME: why? +use ::bok::repository; + +pub mod pkgs { + pub mod one { + pub use crate::repos::pkgs::one::*; + } + pub mod two { + pub use crate::repos::pkgs::two::*; + } +} + +#[::bok::repository(super::r1::R1)] +#[::bok::repo_packages(pkgs::two::Two)] +#[derive(::std::default::Default)] +pub struct R2 { + r2: i32, +} + +#[::bok::repo_impl] +impl R2 {} + +/* +impl Pkgs2 { + /// override the package `two` options from the base repostiory (Pkgs1) + pub fn two(&self) -> Two { + use ::bok::PkgBuilder; + let pkg: Box = Two::builder() + .my_attr(42) + .build() + .expect("Can't build package Two"); + + let two = pkg.as_any().downcast_ref::().unwrap(); + two.clone() + } +} +*/ diff --git a/bok/src/lib.rs b/bok/src/lib.rs index ba8575c..70fdbde 100644 --- a/bok/src/lib.rs +++ b/bok/src/lib.rs @@ -126,6 +126,8 @@ pub trait PkgBuilder: ::core::fmt::Debug + ::std::any::Any { fn name(&self) -> crate::PkgName; fn path(&self) -> crate::Path; fn version(&self) -> crate::Version; + fn as_any(&self) -> &dyn ::std::any::Any; + fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any; fn default_unused(&mut self) -> &mut dyn crate::PkgBuilder; fn build( &mut self,