From 860659548ffe2d402e3e4dbfb4e10cf7416719e0 Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Mon, 11 Nov 2024 12:31:16 +0100 Subject: [PATCH] {Pkg,Repo}Name initial Collection Signed-off-by: Luca Fulchir --- bok-macro/src/lib.rs | 23 ++++++-- bok-utils/src/main.rs | 5 +- bok/src/collection.rs | 44 ++++++++++++++++ bok/src/lib.rs | 66 ++++++++++++++--------- bok/src/names.rs | 120 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 bok/src/collection.rs create mode 100644 bok/src/names.rs diff --git a/bok-macro/src/lib.rs b/bok-macro/src/lib.rs index 5cbca69..588ec74 100644 --- a/bok-macro/src/lib.rs +++ b/bok-macro/src/lib.rs @@ -77,8 +77,8 @@ pub fn derive_repository(input: TokenStream) -> TokenStream { let base_type = elements .iter() .find_map(|field| { - if let Some(name) = &field.ident { - if name != "base" { + if let Some(field_name) = &field.ident { + if field_name != "base" { None } else { let t = &field.ty; @@ -91,7 +91,14 @@ pub fn derive_repository(input: TokenStream) -> TokenStream { .expect("can't find base value. Add #[repository] to your struct"); let expanded = quote! { - impl ::bok::Repository for #name {} + impl ::bok::Repository for #name { + fn name(&self) -> ::bok::RepoName { + (module_path!().to_owned() + "::" + ::std::stringify!(#name)).as_str().into() + } + fn path(&self) -> ::bok::Path<::bok::RepoName> { + (module_path!().to_owned() + "::" + ::std::stringify!(#name)).as_str().into() + } + } impl ::std::ops::Deref for #name { type Target = #base_type; fn deref(&self) -> &#base_type { @@ -221,8 +228,13 @@ pub fn impl_package(_attrs: TokenStream, input: TokenStream) -> TokenStream { _ => panic!("impl_package expected path"), }; let name: ::syn::ImplItem = ::syn::parse_quote! { - fn name(&self) -> &'static str { - ::std::stringify!(#name_pkg) + fn name(&self) -> ::bok::PkgName { + (module_path!().to_owned() + "::" + ::std::stringify!(#name_pkg)).as_str().into() + } + }; + let path: ::syn::ImplItem = ::syn::parse_quote! { + fn path(&self) -> ::bok::Path<::bok::PkgName> { + (module_path!().to_owned() + "::" + ::std::stringify!(#name_pkg)).as_str().into() } }; let version: ::syn::ImplItem = ::syn::parse_quote! { @@ -279,6 +291,7 @@ pub fn impl_package(_attrs: TokenStream, input: TokenStream) -> TokenStream { } ast.items.push(name); + ast.items.push(path); ast.items.push(version); ast.items.push(base); ast.items.push(base_mut); diff --git a/bok-utils/src/main.rs b/bok-utils/src/main.rs index 51ca99e..244fd74 100644 --- a/bok-utils/src/main.rs +++ b/bok-utils/src/main.rs @@ -39,6 +39,9 @@ impl TP for P { fn main() { let pkgs1 = pkgs::Pkgs1::default(); let pkgs2 = pkgs::Pkgs2::default(); + use ::bok::Repository; + println!("pkgs1: {}", pkgs1.name()); + println!("pkgs2: {}", pkgs2.name()); let mut pb: pkgs::one::OneBuilder = pkgs1.one_builder(); @@ -50,7 +53,7 @@ fn main() { let m_pkg = pb.default_unused().build(); println!("m_pb2: {:?}", m_pkg); if let Ok(pkg) = m_pkg { - println!("one: {:?}", pkg); + println!("one: {}: {:?}", pkg.name(), pkg); println!("hash one: {}", pkg.hash()); println!("hash one code: {}", pkg.hash_code()); } diff --git a/bok/src/collection.rs b/bok/src/collection.rs new file mode 100644 index 0000000..358c896 --- /dev/null +++ b/bok/src/collection.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. + */ + +use ::std::{ + collections::HashMap, + sync::{Arc, RwLock}, + vec::Vec, +}; + +type ArcLock = Arc>; +type PkgMap = HashMap>; + +/// Collection of packages, subset of what is present on one repository only +pub struct Collection { + repos: RwLock>>, + pkgs: RwLock, + repos_pkgs: RwLock>, + //repos_pkgs: RwLock>, +} + +impl Collection { + pub fn new() -> Collection { + const PKGNUM: usize = 512; + Collection { + repos: RwLock::new(Vec::with_capacity(8)), + pkgs: RwLock::new(HashMap::with_capacity(PKGNUM)), + repos_pkgs: RwLock::new(HashMap::with_capacity(PKGNUM)), + } + } +} diff --git a/bok/src/lib.rs b/bok/src/lib.rs index c994cfc..bbe129c 100644 --- a/bok/src/lib.rs +++ b/bok/src/lib.rs @@ -1,19 +1,25 @@ /* - * 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. - */ + +* 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. +*/ + +mod collection; +mod names; +pub use collection::Collection; +pub use names::{Path, PkgName, RepoName}; pub use ::bok_macro::{ impl_package, package, pkg_fn_to_code, repository, Package, Repository, @@ -80,23 +86,34 @@ macro_rules! packages { } /// Marks your struct as a repository -pub trait Repository: Default {} +pub trait Repository { + fn name(&self) -> RepoName; + fn path(&self) -> Path; +} -/// -/// This is an empty Package List. Will be available in the main library +/// This is an empty Package List. #[derive(::std::default::Default)] pub struct RepositoryEmpty {} -impl Repository for RepositoryEmpty {} +impl Repository for RepositoryEmpty { + fn name(&self) -> RepoName { + "RepositoryEmpty".into() + } + fn path(&self) -> Path { + "::bok::RepositoryEmpty".into() + } +} /// Print the code of the package pub trait PkgCode { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result; } + /// Implement common package operations pub trait Pkg: PkgCode + ::core::fmt::Debug + ::core::fmt::Display + ::std::any::Any { - fn name(&self) -> &'static str; + fn name(&self) -> PkgName; + fn path(&self) -> Path; fn version(&self) -> &Version; fn base(&self) -> ::core::option::Option<&dyn Pkg>; fn base_mut(&mut self) -> ::core::option::Option<&mut dyn Pkg>; @@ -193,8 +210,11 @@ impl PkgCode for PkgEmpty { } impl Pkg for PkgEmpty { - fn name(&self) -> &'static str { - "package_empty" + fn name(&self) -> PkgName { + "PkgEmpty".into() + } + fn path(&self) -> Path { + "::bok::Pkg::PkgEmpty".into() } fn version(&self) -> &Version { &self.version @@ -305,8 +325,6 @@ impl ::std::fmt::Display for Hash { } } -pub struct Collection {} - /* pub enum Value { /// Set, only once per diff --git a/bok/src/names.rs b/bok/src/names.rs new file mode 100644 index 0000000..0c15ddd --- /dev/null +++ b/bok/src/names.rs @@ -0,0 +1,120 @@ +/* + +* 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. +*/ + +/// Strong typedef for a repository name +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)] +pub struct RepoName(pub String); +impl ::std::fmt::Display for RepoName { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.0) + } +} +impl From for RepoName { + fn from(raw: String) -> RepoName { + RepoName(raw) + } +} +impl From<&str> for RepoName { + fn from(raw: &str) -> RepoName { + RepoName(raw.to_owned()) + } +} + +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone)] +pub struct Path { + pub path: Vec, + pub name: T, +} +impl<'a, T> Path +where + T: From<&'a str>, +{ + pub fn new(raw: &'a str) -> Path { + Path { + path: Vec::new(), + name: raw.into(), + } + } +} +impl<'a, T> From<&'a str> for Path +where + T: From<&'a str>, +{ + fn from(raw: &'a str) -> Self { + Path::new(raw) + } +} + +impl ::std::fmt::Debug for Path +where + T: ::std::fmt::Display + ::std::fmt::Debug, +{ + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + let mut path = "".to_owned(); + for p in self.path.iter() { + path += "::"; + path += p.as_str(); + } + write!(f, "{}::{}", path, self.name) + } +} +impl ::std::fmt::Display for Path +where + T: ::std::fmt::Display + ::std::fmt::Debug, +{ + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{:?}", self) + } +} + +/// Marks your struct as a repository +pub trait Repository { + fn name(&self) -> RepoName; + fn path(&self) -> Path; +} + +/// This is an empty Package List. +#[derive(::std::default::Default)] +pub struct RepositoryEmpty {} +impl Repository for RepositoryEmpty { + fn name(&self) -> RepoName { + "RepositoryEmpty".into() + } + fn path(&self) -> Path { + Path::new("::bok::RepositoryEmpty") + } +} + +/// Strong typedef for a package name +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)] +pub struct PkgName(pub String); +impl ::std::fmt::Display for PkgName { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.0) + } +} +impl From for PkgName { + fn from(raw: String) -> PkgName { + PkgName(raw) + } +} +impl From<&str> for PkgName { + fn from(raw: &str) -> PkgName { + PkgName(raw.to_owned()) + } +}