repo: get list of pkgs and boxed pkg
Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
parent
f08ae227a2
commit
631c3a19e5
@ -278,7 +278,72 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream {
|
||||
|
||||
let name = input.ident.clone();
|
||||
|
||||
let expanded = quote! {
|
||||
let ::syn::Data::Struct(items) = &input.data else {
|
||||
use ::syn::spanned::Spanned;
|
||||
return ::syn::Error::new(
|
||||
input.span(),
|
||||
"#[derive(::bok::Repository)]: not called on a struct",
|
||||
)
|
||||
.to_compile_error()
|
||||
.into();
|
||||
};
|
||||
|
||||
if items
|
||||
.fields
|
||||
.iter()
|
||||
.find(|&f| {
|
||||
f.ident
|
||||
.as_ref()
|
||||
.is_some_and(|id| id.to_string() == "_bok_repo")
|
||||
})
|
||||
.is_none()
|
||||
{
|
||||
use ::syn::spanned::Spanned;
|
||||
return ::syn::Error::new(
|
||||
input.span(),
|
||||
"#[derive(::bok::Repository)]: struct is not a bok repo. use \
|
||||
`#[::bok::repository(..)]` first",
|
||||
)
|
||||
.to_compile_error()
|
||||
.into();
|
||||
}
|
||||
// holds the list of all package names, snake case
|
||||
let mut all_pkgs =
|
||||
Vec::<(String, ::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 path = {
|
||||
let ::syn::Type::Path(phantom_path) = &it.ty else {
|
||||
continue;
|
||||
};
|
||||
let segment = phantom_path.path.segments.last().unwrap();
|
||||
let ::syn::PathArguments::AngleBracketed(bracketed) =
|
||||
&segment.arguments
|
||||
else {
|
||||
panic!("derive: phantom without anglebracket?");
|
||||
};
|
||||
let ::syn::GenericArgument::Type(::syn::Type::Path(t)) =
|
||||
bracketed.args.first().expect("phantom bracketed, no args")
|
||||
else {
|
||||
panic!(
|
||||
"derive: phantom bracketed, generic not a type path"
|
||||
);
|
||||
};
|
||||
t.path.clone()
|
||||
};
|
||||
let name = id_str.strip_prefix("_p_").unwrap().to_owned();
|
||||
all_pkgs.push((name, path));
|
||||
}
|
||||
}
|
||||
all_pkgs.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
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();
|
||||
|
||||
quote! {
|
||||
impl ::bok::Repository for #name {
|
||||
fn name(&self) -> ::bok::RepoName {
|
||||
(module_path!().to_owned() + "::" + ::std::stringify!(#name)).as_str().into()
|
||||
@ -286,10 +351,22 @@ pub(crate) fn derive_repository(input: TokenStream) -> TokenStream {
|
||||
fn path(&self) -> ::bok::Path<::bok::RepoName> {
|
||||
(module_path!().to_owned() + "::" + ::std::stringify!(#name)).as_str().into()
|
||||
}
|
||||
fn pkg_list(&self) -> &[&'static str] {
|
||||
const PKGS : [&'static str; #pkgs_num] = [
|
||||
#(#pkg_names),
|
||||
*
|
||||
];
|
||||
&PKGS
|
||||
}
|
||||
};
|
||||
|
||||
TokenStream::from(expanded)
|
||||
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())),)
|
||||
*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
}.into()
|
||||
}
|
||||
struct PathList(Vec<::syn::Path>);
|
||||
|
||||
|
@ -50,6 +50,8 @@ macro_rules! moduse {
|
||||
pub trait Repository: ::core::fmt::Debug {
|
||||
fn name(&self) -> RepoName;
|
||||
fn path(&self) -> Path<RepoName>;
|
||||
fn pkg_list(&self) -> &[&'static str];
|
||||
fn get(&self, pkg_name: &str) -> Option<::std::boxed::Box<dyn Pkg>>;
|
||||
}
|
||||
|
||||
/// This is an empty Package List.
|
||||
@ -66,6 +68,13 @@ impl Repository for RepositoryEmpty {
|
||||
fn path(&self) -> Path<RepoName> {
|
||||
"::bok::RepositoryEmpty".into()
|
||||
}
|
||||
fn pkg_list(&self) -> &[&'static str] {
|
||||
const PKGS: [&'static str; 0] = [];
|
||||
&PKGS
|
||||
}
|
||||
fn get(&self, _pkg_name: &str) -> Option<::std::boxed::Box<dyn Pkg>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Print the code of the package
|
||||
|
Loading…
Reference in New Issue
Block a user