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;
return ::syn::Error::new(
local.fields.span(),
"unnamed fields are not supported",
"#[::bok::package()]: unnamed fields are not supported",
)
.to_compile_error()
.into();
};
let local_attrs = local.attrs.iter();
let generics = local.generics;
let ident = local.ident;
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);
@ -72,7 +84,7 @@ pub(crate) fn package(
use ::syn::spanned::Spanned;
return ::syn::Error::new(
base.fields.span(),
"unnamed fields are not supported",
"#[::bok::package(..)]: base: unnamed fields are not supported",
)
.to_compile_error()
.into();
@ -95,8 +107,14 @@ pub(crate) fn package(
_bok_base: ::std::marker::PhantomData<#source_path>
})
.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(base_marker);
base_fields_extra.push(repo_marker);
}
None => {
return ::syn::Error::new(
@ -114,7 +132,10 @@ pub(crate) fn package(
for f in base_fields.named.iter() {
let Some(id) = &f.ident else { continue };
// 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;
}
// compiler error if you try to extend a package while
@ -144,12 +165,13 @@ pub(crate) fn package(
let mut all_fields = Vec::new();
all_fields.extend(local_fields.named.iter());
all_fields.extend(base_fields_extra.iter());
quote! {
#(#local_attrs)
*
#[::macro_magic::export_tokens]
#[derive(::bok::Package, ::std::fmt::Debug, Clone)]
#vis struct #ident<#generics> {
#vis struct #ident #generics #where_clause{
#(#all_fields),
*
}
@ -175,7 +197,7 @@ pub(crate) fn deps_build(
};
let local_attrs = local.attrs.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 vis = local.vis;
@ -190,7 +212,7 @@ pub(crate) fn deps_build(
quote! {
#(#local_attrs)
*
#vis struct #ident<#generics> {
#vis struct #ident #generics #where_clause{
#(#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(path);
ast.items.push(version);
@ -584,7 +617,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
};
let all_fields = elements.iter().filter_map(|field| {
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);
}
}
@ -594,7 +630,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
let all_fields3 = all_fields.clone();
let all_fields_mut = elements.iter().filter_map(|field| {
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()));
}
}
@ -602,7 +641,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
});
let all_types = elements.iter().filter_map(|field| {
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);
}
}
@ -611,7 +653,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
let all_types2 = all_types.clone();
let non_opt_fields = elements.iter().filter_map(|field| {
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;
}
}
@ -630,7 +675,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
});
let opt_fields = elements.iter().filter_map(|field| {
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;
}
}
@ -649,7 +697,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
});
let non_opt_types = elements.iter().filter_map(|field| {
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;
}
}
@ -668,7 +719,10 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
});
let opt_types = elements.iter().filter_map(|field| {
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;
}
}
@ -719,14 +773,20 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
}
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<'_>)
->::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<'_>)
->::core::fmt::Result
{
@ -786,15 +846,18 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
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 {
self
}
pub fn as_pkg_mut(&mut self) -> &mut dyn ::bok::Pkg {
self
}
pub fn builder() -> #name_builder {
#name_builder::default()
pub fn builder() -> #name_builder<R> {
#name_builder::<R>::default()
}
#(pub fn #all_fields2(&self) -> &#all_types {
&self.#all_fields2
@ -804,25 +867,32 @@ pub(crate) fn derive_package(input: TokenStream) -> TokenStream {
})*
}
#[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>,)*
#(#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 {
use ::bok::Pkg;
#name::default().name()
#name::<R>::default().name()
}
fn path(&self) -> ::bok::Path<::bok::PkgName> {
use ::bok::Pkg;
#name::default().path()
#name::<R>::default().path()
}
fn version(&self) -> ::bok::Version {
use ::bok::Pkg;
#name::default().version()
#name::<R>::default().version()
}
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() {
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());
})*
Ok(
Box::new(#name {
Box::new(#name::<R> {
_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(),)*
#(#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 {
self
}

View File

@ -74,7 +74,7 @@ pub(crate) fn repository(
_ => true,
}
});
let generics = local.generics;
let (_, generics, where_clause) = local.generics.split_for_impl();
let ident = local.ident;
let vis = local.vis;
@ -149,7 +149,7 @@ pub(crate) fn repository(
*
#[::macro_magic::export_tokens]
#[derive(::bok::Repository, Debug)]
#vis struct #ident<#generics> {
#vis struct #ident #generics #where_clause {
#(#all_fields),
*
}
@ -226,6 +226,10 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream {
let pkgs_num: usize = all_pkgs.len();
let (pkg_names, pkg_types): (Vec<String>, Vec<::syn::Path>) =
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! {
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>> {
match pkg_name {
#(#pkg_names => Some(::std::boxed::Box::new(#pkg_types::default())),)
#(#pkg_names => Some(::std::boxed::Box::new(self.#pkg_ident())),)
*
_ => None,
}
@ -259,7 +263,7 @@ pub(crate) fn repo_packages(
) -> TokenStream {
let local = parse_macro_input!(input as ItemStruct);
let local_attrs = local.attrs.iter();
let generics = local.generics;
let (_, generics, where_clause) = local.generics.split_for_impl();
let ident = local.ident;
let vis = local.vis;
use ::syn::spanned::Spanned;
@ -390,7 +394,7 @@ pub(crate) fn repo_packages(
quote! {
#(#local_attrs)
*
#vis struct #ident<#generics> {
#vis struct #ident #generics #where_clause {
#(#all_fields),
*
}
@ -443,7 +447,7 @@ pub(crate) fn repo_impl_methods(
}
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 {
return ::syn::Error::new(
proc_macro2::Span::call_site(),
@ -519,9 +523,16 @@ pub(crate) fn repo_impl_methods(
// don't try to add it again
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! {
pub fn #pkg_name(&self) -> #t_id {
#t_id::default()
#t_id_build::default()
}
};
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() {
let bok_dep_trait = {
let mut tmp = p_type.clone();
tmp.segments.last_mut().unwrap().ident = quote::format_ident!(
"BokDeps{}",
tmp.segments.last().unwrap().ident
);
let last = tmp.segments.last_mut().unwrap();
last.ident = quote::format_ident!("BokDeps{}", last.ident);
last.arguments = ::syn::PathArguments::None;
tmp
};
let pkg_trait_impl = &bok_dep_trait;
@ -552,7 +562,7 @@ pub(crate) fn repo_impl_methods(
quote! {
#(#local_attrs)
*
impl #local_ident<#generics> {
impl #local_ident #generics #where_clause {
#(#items)
*
#(#new_fn)
@ -576,7 +586,7 @@ pub(crate) fn repo_impl_pkg_deps(
.expect("#[::bok_macro::repo_impl_pkg_deps()]: no trait found")
.1;
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 deps = Vec::<::syn::TraitItemFn>::new();
@ -601,7 +611,7 @@ pub(crate) fn repo_impl_pkg_deps(
quote! {
#(#local_attrs)
*
impl #impl_trait for #ident<#generics> {
impl #impl_trait for #ident #generics #where_clause {
#(#deps)
*
}

View File

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

View File

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

View File

@ -16,8 +16,6 @@
*/
use ::bok::package;
//use ::bok::{package, PkgEmpty};
//use ::bok::*;
/// Example package
/// Automatically implements `.builder().my_attr(42).build()` pattern
@ -27,10 +25,14 @@ pub struct One {
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 {
One {
_bok_base: ::std::marker::PhantomData::default(),
_bok_repo: ::std::marker::PhantomData::default(),
my_attr: 1,
version: ::bok::Version {
major: 0,

View File

@ -19,15 +19,19 @@ use ::bok::package;
/// Example package
#[::bok::package(::bok::PkgEmpty)]
#[::bok::deps_build(super::One)]
#[::bok::deps_build(super::One<R>)]
pub struct Three {
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 {
Three {
_bok_base: ::std::marker::PhantomData::default(),
_bok_repo: ::std::marker::PhantomData::default(),
version: ::bok::Version {
major: 0,
minor: 0,

View File

@ -18,16 +18,20 @@
use ::bok::package;
/// Example package
#[::bok::package(super::one::One)]
#[::bok::deps_build(super::one::One)]
#[::bok::package(super::one::One<R>)]
#[::bok::deps_build(super::one::One<R>)]
pub struct Two {
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 {
Two {
_bok_base: ::std::marker::PhantomData::default(),
_bok_repo: ::std::marker::PhantomData::default(),
my_attr: 2,
my_attr2: 2,
version: ::bok::Version {