probably wrong way to connect repo to pkgs

Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
Luca Fulchir 2024-12-03 17:26:53 +01:00
parent 00e93ce612
commit 46b7e9282d
Signed by: luca.fulchir
GPG Key ID: 8F6440603D13A78E
7 changed files with 148 additions and 54 deletions

View File

@ -55,15 +55,27 @@ pub(crate) fn package(
use ::syn::spanned::Spanned; use ::syn::spanned::Spanned;
return ::syn::Error::new( return ::syn::Error::new(
local.fields.span(), local.fields.span(),
"unnamed fields are not supported", "#[::bok::package()]: unnamed fields are not supported",
) )
.to_compile_error() .to_compile_error()
.into(); .into();
}; };
let local_attrs = local.attrs.iter(); let local_attrs = local.attrs.iter();
let generics = local.generics;
let ident = local.ident; let ident = local.ident;
let vis = local.vis; let vis = local.vis;
let local_generics = local.generics;
if local_generics.params.len() != 0 {
return ::syn::Error::new(
local_span,
"#[::bok::package()]: a package can not have generics",
)
.to_compile_error()
.into();
};
let generic_struct: ::syn::ItemStruct = ::syn::parse_quote! {
pub struct test<R> where R: ::std::fmt::Debug + 'static {}
};
let (_, generics, where_clause) = generic_struct.generics.split_for_impl();
let source_path = parse_macro_input!(__source_path as ::syn::Path); let source_path = parse_macro_input!(__source_path as ::syn::Path);
@ -72,7 +84,7 @@ pub(crate) fn package(
use ::syn::spanned::Spanned; use ::syn::spanned::Spanned;
return ::syn::Error::new( return ::syn::Error::new(
base.fields.span(), base.fields.span(),
"unnamed fields are not supported", "#[::bok::package(..)]: base: unnamed fields are not supported",
) )
.to_compile_error() .to_compile_error()
.into(); .into();
@ -95,8 +107,14 @@ pub(crate) fn package(
_bok_base: ::std::marker::PhantomData<#source_path> _bok_base: ::std::marker::PhantomData<#source_path>
}) })
.unwrap(); .unwrap();
let repo_marker = ::syn::Field::parse_named
.parse2(quote! {
_bok_repo: ::std::marker::PhantomData<R>
})
.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);
} }
None => { None => {
return ::syn::Error::new( return ::syn::Error::new(
@ -114,7 +132,10 @@ pub(crate) fn package(
for f in base_fields.named.iter() { for f in base_fields.named.iter() {
let Some(id) = &f.ident else { continue }; let Some(id) = &f.ident else { continue };
// don't add 'version' again // don't add 'version' again
if id.to_string() == "version" || id.to_string() == "_bok_base" { if id.to_string() == "version"
|| id.to_string() == "_bok_base"
|| id.to_string() == "_bok_repo"
{
continue; continue;
} }
// compiler error if you try to extend a package while // compiler error if you try to extend a package while
@ -144,12 +165,13 @@ pub(crate) fn package(
let mut all_fields = Vec::new(); let mut all_fields = Vec::new();
all_fields.extend(local_fields.named.iter()); all_fields.extend(local_fields.named.iter());
all_fields.extend(base_fields_extra.iter()); all_fields.extend(base_fields_extra.iter());
quote! { quote! {
#(#local_attrs) #(#local_attrs)
* *
#[::macro_magic::export_tokens] #[::macro_magic::export_tokens]
#[derive(::bok::Package, ::std::fmt::Debug, Clone)] #[derive(::bok::Package, ::std::fmt::Debug, Clone)]
#vis struct #ident<#generics> { #vis struct #ident #generics #where_clause{
#(#all_fields), #(#all_fields),
* *
} }
@ -175,7 +197,7 @@ pub(crate) fn deps_build(
}; };
let local_attrs = local.attrs.iter(); let local_attrs = local.attrs.iter();
let local_fields = local_fields.named.iter(); let local_fields = local_fields.named.iter();
let generics = local.generics; let (_, generics, where_clause) = local.generics.split_for_impl();
let ident = local.ident; let ident = local.ident;
let vis = local.vis; let vis = local.vis;
@ -190,7 +212,7 @@ pub(crate) fn deps_build(
quote! { quote! {
#(#local_attrs) #(#local_attrs)
* *
#vis struct #ident<#generics> { #vis struct #ident #generics #where_clause{
#(#local_fields), #(#local_fields),
* *
} }
@ -480,6 +502,17 @@ pub(crate) fn package_impl_base_add(
} }
} }
let pkg_type = ast.self_ty.clone();
let generic_struct: ::syn::ItemImpl = ::syn::parse_quote! {
impl<R> test for #pkg_type <R>
where
R: ::std::fmt::Debug + 'static
{}
};
ast.generics = generic_struct.generics;
ast.self_ty = generic_struct.self_ty;
ast.items.push(name); ast.items.push(name);
ast.items.push(path); ast.items.push(path);
ast.items.push(version); ast.items.push(version);
@ -584,7 +617,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
}; };
let all_fields = elements.iter().filter_map(|field| { let all_fields = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() != "version" && id.to_string() != "_bok_base" { if id.to_string() != "version"
&& id.to_string() != "_bok_base"
&& id.to_string() != "_bok_repo"
{
return Some(&field.ident); return Some(&field.ident);
} }
} }
@ -594,7 +630,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
let all_fields3 = all_fields.clone(); let all_fields3 = all_fields.clone();
let all_fields_mut = elements.iter().filter_map(|field| { let all_fields_mut = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() != "version" && id.to_string() != "_bok_base" { if id.to_string() != "version"
&& id.to_string() != "_bok_base"
&& id.to_string() != "_bok_repo"
{
return Some(quote::format_ident!("{}_mut", id.to_string())); return Some(quote::format_ident!("{}_mut", id.to_string()));
} }
} }
@ -602,7 +641,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
}); });
let all_types = elements.iter().filter_map(|field| { let all_types = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() != "version" && id.to_string() != "_bok_base" { if id.to_string() != "version"
&& id.to_string() != "_bok_base"
&& id.to_string() != "_bok_repo"
{
return Some(&field.ty); return Some(&field.ty);
} }
} }
@ -611,7 +653,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
let all_types2 = all_types.clone(); let all_types2 = all_types.clone();
let non_opt_fields = elements.iter().filter_map(|field| { let non_opt_fields = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() == "version" || id.to_string() == "_bok_base" { if id.to_string() == "version"
|| id.to_string() == "_bok_base"
|| id.to_string() == "_bok_repo"
{
return None; return None;
} }
} }
@ -630,7 +675,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
}); });
let opt_fields = elements.iter().filter_map(|field| { let opt_fields = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() == "version" || id.to_string() == "_bok_base" { if id.to_string() == "version"
|| id.to_string() == "_bok_base"
|| id.to_string() == "_bok_repo"
{
return None; return None;
} }
} }
@ -649,7 +697,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
}); });
let non_opt_types = elements.iter().filter_map(|field| { let non_opt_types = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() == "version" || id.to_string() == "_bok_base" { if id.to_string() == "version"
|| id.to_string() == "_bok_base"
|| id.to_string() == "_bok_repo"
{
return None; return None;
} }
} }
@ -668,7 +719,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
}); });
let opt_types = elements.iter().filter_map(|field| { let opt_types = elements.iter().filter_map(|field| {
if let Some(id) = field.ident.clone() { if let Some(id) = field.ident.clone() {
if id.to_string() == "version" || id.to_string() == "_bok_base" { if id.to_string() == "version"
|| id.to_string() == "_bok_base"
|| id.to_string() == "_bok_repo"
{
return None; return None;
} }
} }
@ -719,14 +773,20 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
} }
let expanded = quote! { let expanded = quote! {
impl ::core::fmt::Display for #name { impl<R> ::core::fmt::Display for #name<R>
where
R: ::std::fmt::Debug
{
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
->::core::fmt::Result ->::core::fmt::Result
{ {
<#name as ::bok::PkgCode>::fmt(self, f) <#name<R> as ::bok::PkgCode>::fmt(self, f)
} }
} }
impl ::bok::PkgCode for #name { impl<R> ::bok::PkgCode for #name<R>
where
R: ::std::fmt::Debug +'static
{
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
->::core::fmt::Result ->::core::fmt::Result
{ {
@ -786,15 +846,18 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
f.write_str(&formatted) f.write_str(&formatted)
} }
} }
impl #name { impl<R> #name<R>
where
R: ::std::fmt::Debug +'static + ::core::default::Default
{
pub fn as_pkg(&self) -> &dyn ::bok::Pkg { pub fn as_pkg(&self) -> &dyn ::bok::Pkg {
self self
} }
pub fn as_pkg_mut(&mut self) -> &mut dyn ::bok::Pkg { pub fn as_pkg_mut(&mut self) -> &mut dyn ::bok::Pkg {
self self
} }
pub fn builder() -> #name_builder { pub fn builder() -> #name_builder<R> {
#name_builder::default() #name_builder::<R>::default()
} }
#(pub fn #all_fields2(&self) -> &#all_types { #(pub fn #all_fields2(&self) -> &#all_types {
&self.#all_fields2 &self.#all_fields2
@ -804,25 +867,32 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
})* })*
} }
#[derive(::std::default::Default, ::std::fmt::Debug)] #[derive(::std::default::Default, ::std::fmt::Debug)]
pub struct #name_builder { pub struct #name_builder<R>
where
R: ::std::fmt::Debug +'static
{
_bok_repo: ::std::marker::PhantomData<R>,
#(#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>,)*
} }
impl ::bok::PkgBuilder for #name_builder2 { impl<R> ::bok::PkgBuilder for #name_builder2<R>
where
R: ::std::fmt::Debug + 'static
{
fn name(&self) -> ::bok::PkgName { fn name(&self) -> ::bok::PkgName {
use ::bok::Pkg; use ::bok::Pkg;
#name::default().name() #name::<R>::default().name()
} }
fn path(&self) -> ::bok::Path<::bok::PkgName> { fn path(&self) -> ::bok::Path<::bok::PkgName> {
use ::bok::Pkg; use ::bok::Pkg;
#name::default().path() #name::<R>::default().path()
} }
fn version(&self) -> ::bok::Version { fn version(&self) -> ::bok::Version {
use ::bok::Pkg; use ::bok::Pkg;
#name::default().version() #name::<R>::default().version()
} }
fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder { fn default_unused(&mut self) -> &mut dyn ::bok::PkgBuilder {
let def = #name::default(); let def = #name::<R>::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);
})* })*
@ -834,16 +904,20 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
return ::std::result::Result::Err("unset field".into()); return ::std::result::Result::Err("unset field".into());
})* })*
Ok( Ok(
Box::new(#name { Box::new(#name::<R> {
_bok_base: ::std::marker::PhantomData::default(), _bok_base: ::std::marker::PhantomData::default(),
version: #name::default().version, _bok_repo: ::std::marker::PhantomData::default(),
version: #name::<R>::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(),)*
}) })
) )
} }
} }
impl #name_builder3 { impl<R> #name_builder3<R>
where
R: ::std::fmt::Debug +'static
{
pub fn as_any(&self) -> &dyn ::std::any::Any { pub fn as_any(&self) -> &dyn ::std::any::Any {
self self
} }

View File

@ -74,7 +74,7 @@ pub(crate) fn repository(
_ => true, _ => true,
} }
}); });
let generics = local.generics; let (_, generics, where_clause) = local.generics.split_for_impl();
let ident = local.ident; let ident = local.ident;
let vis = local.vis; let vis = local.vis;
@ -149,7 +149,7 @@ pub(crate) fn repository(
* *
#[::macro_magic::export_tokens] #[::macro_magic::export_tokens]
#[derive(::bok::Repository, Debug)] #[derive(::bok::Repository, Debug)]
#vis struct #ident<#generics> { #vis struct #ident #generics #where_clause {
#(#all_fields), #(#all_fields),
* *
} }
@ -226,6 +226,10 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream {
let pkgs_num: usize = all_pkgs.len(); let pkgs_num: usize = all_pkgs.len();
let (pkg_names, pkg_types): (Vec<String>, Vec<::syn::Path>) = let (pkg_names, pkg_types): (Vec<String>, Vec<::syn::Path>) =
all_pkgs.into_iter().map(|(a, b)| (a, b)).unzip(); all_pkgs.into_iter().map(|(a, b)| (a, b)).unzip();
let pkg_ident = pkg_types
.iter()
.map(|p| p.segments.last().unwrap().ident.clone())
.collect::<Vec<::syn::Ident>>();
quote! { quote! {
impl ::bok::Repository for #name { impl ::bok::Repository for #name {
@ -244,7 +248,7 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream {
} }
fn get(&self, pkg_name: &str) -> Option<::std::boxed::Box<dyn ::bok::Pkg>> { fn get(&self, pkg_name: &str) -> Option<::std::boxed::Box<dyn ::bok::Pkg>> {
match pkg_name { match pkg_name {
#(#pkg_names => Some(::std::boxed::Box::new(#pkg_types::default())),) #(#pkg_names => Some(::std::boxed::Box::new(self.#pkg_ident())),)
* *
_ => None, _ => None,
} }
@ -259,7 +263,7 @@ pub(crate) fn repo_packages(
) -> TokenStream { ) -> TokenStream {
let local = parse_macro_input!(input as ItemStruct); let local = parse_macro_input!(input as ItemStruct);
let local_attrs = local.attrs.iter(); let local_attrs = local.attrs.iter();
let generics = local.generics; let (_, generics, where_clause) = local.generics.split_for_impl();
let ident = local.ident; let ident = local.ident;
let vis = local.vis; let vis = local.vis;
use ::syn::spanned::Spanned; use ::syn::spanned::Spanned;
@ -390,7 +394,7 @@ pub(crate) fn repo_packages(
quote! { quote! {
#(#local_attrs) #(#local_attrs)
* *
#vis struct #ident<#generics> { #vis struct #ident #generics #where_clause {
#(#all_fields), #(#all_fields),
* *
} }
@ -443,7 +447,7 @@ pub(crate) fn repo_impl_methods(
} }
let local_attrs = local.attrs.iter(); let local_attrs = local.attrs.iter();
let generics = local.generics; let (_, generics, where_clause) = local.generics.split_for_impl();
let ::syn::Type::Path(local_tp) = local.self_ty.as_ref() else { let ::syn::Type::Path(local_tp) = local.self_ty.as_ref() else {
return ::syn::Error::new( return ::syn::Error::new(
proc_macro2::Span::call_site(), proc_macro2::Span::call_site(),
@ -519,9 +523,16 @@ pub(crate) fn repo_impl_methods(
// don't try to add it again // don't try to add it again
continue; continue;
} }
let mut t_id_build = t_id.clone();
if let ::syn::PathArguments::AngleBracketed(args) =
&mut t_id_build.segments.last_mut().unwrap().arguments
{
args.colon2_token = Some(::syn::token::PathSep::default());
}
let pkg_fn: ::syn::ImplItemFn = ::syn::parse_quote! { let pkg_fn: ::syn::ImplItemFn = ::syn::parse_quote! {
pub fn #pkg_name(&self) -> #t_id { pub fn #pkg_name(&self) -> #t_id {
#t_id::default() #t_id_build::default()
} }
}; };
fn_to_add.push(pkg_fn); fn_to_add.push(pkg_fn);
@ -534,10 +545,9 @@ pub(crate) fn repo_impl_methods(
for p_type in all_pkgs_types.into_iter() { for p_type in all_pkgs_types.into_iter() {
let bok_dep_trait = { let bok_dep_trait = {
let mut tmp = p_type.clone(); let mut tmp = p_type.clone();
tmp.segments.last_mut().unwrap().ident = quote::format_ident!( let last = tmp.segments.last_mut().unwrap();
"BokDeps{}", last.ident = quote::format_ident!("BokDeps{}", last.ident);
tmp.segments.last().unwrap().ident last.arguments = ::syn::PathArguments::None;
);
tmp tmp
}; };
let pkg_trait_impl = &bok_dep_trait; let pkg_trait_impl = &bok_dep_trait;
@ -552,7 +562,7 @@ pub(crate) fn repo_impl_methods(
quote! { quote! {
#(#local_attrs) #(#local_attrs)
* *
impl #local_ident<#generics> { impl #local_ident #generics #where_clause {
#(#items) #(#items)
* *
#(#new_fn) #(#new_fn)
@ -576,7 +586,7 @@ pub(crate) fn repo_impl_pkg_deps(
.expect("#[::bok_macro::repo_impl_pkg_deps()]: no trait found") .expect("#[::bok_macro::repo_impl_pkg_deps()]: no trait found")
.1; .1;
let local_attrs = local.attrs.iter(); let local_attrs = local.attrs.iter();
let generics = local.generics; let (_, generics, where_clause) = local.generics.split_for_impl();
let ident = &local.self_ty; let ident = &local.self_ty;
//let deps = Vec::<::syn::TraitItemFn>::new(); //let deps = Vec::<::syn::TraitItemFn>::new();
@ -601,7 +611,7 @@ pub(crate) fn repo_impl_pkg_deps(
quote! { quote! {
#(#local_attrs) #(#local_attrs)
* *
impl #impl_trait for #ident<#generics> { impl #impl_trait for #ident #generics #where_clause {
#(#deps) #(#deps)
* *
} }

View File

@ -37,7 +37,7 @@ impl TP for P {
*/ */
fn main() { fn main() {
let one = repos::pkgs::one::One::default(); //let one = repos::pkgs::one::One::default();
let pkgs1 = repos::Pkgs1::default(); let pkgs1 = repos::Pkgs1::default();
let pkgs2 = repos::Pkgs2::default(); let pkgs2 = repos::Pkgs2::default();

View File

@ -30,7 +30,7 @@ use ::bok::repository;
/// ///
/// Base repository with some packages /// Base repository with some packages
#[::bok::repository(::bok::RepositoryEmpty)] #[::bok::repository(::bok::RepositoryEmpty)]
#[::bok::repo_packages(pkgs::one::One)] #[::bok::repo_packages(pkgs::one::One<Self>)]
#[derive(::std::default::Default)] #[derive(::std::default::Default)]
pub struct Pkgs1 { pub struct Pkgs1 {
r1: i32, r1: i32,
@ -42,7 +42,7 @@ impl Pkgs1 {}
/// ///
/// This repository extends and changes Pkgs1 /// This repository extends and changes Pkgs1
#[::bok::repository(Pkgs1)] #[::bok::repository(Pkgs1)]
#[::bok::repo_packages(pkgs::two::Two)] #[::bok::repo_packages(pkgs::two::Two<Self>)]
#[derive(::std::default::Default)] #[derive(::std::default::Default)]
pub struct Pkgs2 { pub struct Pkgs2 {
r2: i32, r2: i32,

View File

@ -16,8 +16,6 @@
*/ */
use ::bok::package; use ::bok::package;
//use ::bok::{package, PkgEmpty};
//use ::bok::*;
/// Example package /// Example package
/// Automatically implements `.builder().my_attr(42).build()` pattern /// Automatically implements `.builder().my_attr(42).build()` pattern
@ -27,10 +25,14 @@ pub struct One {
pub my_attr: u32, pub my_attr: u32,
} }
impl ::std::default::Default for One { impl<R> ::std::default::Default for One<R>
where
R: ::std::fmt::Debug,
{
fn default() -> Self { fn default() -> Self {
One { One {
_bok_base: ::std::marker::PhantomData::default(), _bok_base: ::std::marker::PhantomData::default(),
_bok_repo: ::std::marker::PhantomData::default(),
my_attr: 1, my_attr: 1,
version: ::bok::Version { version: ::bok::Version {
major: 0, major: 0,

View File

@ -19,15 +19,19 @@ use ::bok::package;
/// Example package /// Example package
#[::bok::package(::bok::PkgEmpty)] #[::bok::package(::bok::PkgEmpty)]
#[::bok::deps_build(super::One)] #[::bok::deps_build(super::One<R>)]
pub struct Three { pub struct Three {
pub my_attr: u32, pub my_attr: u32,
} }
impl ::std::default::Default for Three { impl<R> ::std::default::Default for Three<R>
where
R: ::std::fmt::Debug,
{
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(),
version: ::bok::Version { version: ::bok::Version {
major: 0, major: 0,
minor: 0, minor: 0,

View File

@ -18,16 +18,20 @@
use ::bok::package; use ::bok::package;
/// Example package /// Example package
#[::bok::package(super::one::One)] #[::bok::package(super::one::One<R>)]
#[::bok::deps_build(super::one::One)] #[::bok::deps_build(super::one::One<R>)]
pub struct Two { pub struct Two {
pub my_attr2: u32, pub my_attr2: u32,
} }
impl ::std::default::Default for Two { impl<R> ::std::default::Default for Two<R>
where
R: ::std::fmt::Debug,
{
fn default() -> Self { fn default() -> Self {
Two { Two {
_bok_base: ::std::marker::PhantomData::default(), _bok_base: ::std::marker::PhantomData::default(),
_bok_repo: ::std::marker::PhantomData::default(),
my_attr: 2, my_attr: 2,
my_attr2: 2, my_attr2: 2,
version: ::bok::Version { version: ::bok::Version {