2024-12-08 17:08:20 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2024 Luca Fulchir <luca.fulchir@runesauth.com>
|
|
|
|
*
|
|
|
|
* 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 ::proc_macro::TokenStream;
|
|
|
|
use ::quote::quote;
|
|
|
|
use ::syn::parse_macro_input;
|
|
|
|
|
|
|
|
pub(crate) fn collection(
|
|
|
|
attrs: TokenStream,
|
|
|
|
input: TokenStream,
|
|
|
|
) -> TokenStream {
|
|
|
|
let ast = parse_macro_input!(input as ::syn::ItemStruct);
|
|
|
|
if ast.ident.to_string() != "Collection" {
|
|
|
|
use ::syn::spanned::Spanned;
|
|
|
|
return ::syn::Error::new(
|
|
|
|
ast.span(),
|
|
|
|
"#[::bok_macro::collection(..)] should only be called on `struct \
|
|
|
|
Collection{}`",
|
|
|
|
)
|
|
|
|
.to_compile_error()
|
|
|
|
.into();
|
|
|
|
}
|
|
|
|
use crate::PathList;
|
|
|
|
|
|
|
|
let deps_list = parse_macro_input!(attrs as PathList);
|
|
|
|
let mut all_deps_builder = deps_list.0.iter();
|
|
|
|
let name = all_deps_builder.next().expect(
|
|
|
|
"`#[::bok_macro::collection(..)]` must have at least two arguments, \
|
|
|
|
the first is the repo path",
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut asdf = Vec::new();
|
|
|
|
for d in deps_list.0.iter() {
|
|
|
|
let d_str = d
|
|
|
|
.segments
|
|
|
|
.iter()
|
|
|
|
.fold(String::new(), |a, b| a + "_" + &b.ident.to_string());
|
|
|
|
asdf.push(::quote::format_ident!("{}", d_str));
|
|
|
|
}
|
|
|
|
|
|
|
|
quote! {
|
|
|
|
use ::bok_macro::collection_dep;
|
|
|
|
#(
|
|
|
|
const #asdf : u32 = 42;
|
|
|
|
)
|
|
|
|
*
|
|
|
|
#(#[::bok_macro::collection_dep(#all_deps_builder)])
|
|
|
|
*
|
2024-12-13 15:57:46 +00:00
|
|
|
#[derive(::core::fmt::Debug)]
|
2024-12-08 17:08:20 +00:00
|
|
|
pub struct Collection {
|
|
|
|
repo: ::std::sync::Arc<#name>,
|
|
|
|
pkgs: ::std::sync::RwLock<
|
|
|
|
::std::vec::Vec<
|
|
|
|
::std::sync::Arc<
|
|
|
|
dyn ::bok::PkgBuilder>>>,
|
|
|
|
}
|
2024-12-13 09:29:14 +00:00
|
|
|
impl ::bok::Collection for Collection {
|
|
|
|
fn as_any(&self) -> &dyn ::std::any::Any {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
fn as_any_mut(&mut self) -> &mut dyn ::std::any::Any {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
2024-12-08 17:08:20 +00:00
|
|
|
}
|
|
|
|
.into()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) fn collection_dep(
|
|
|
|
attrs: TokenStream,
|
|
|
|
input: TokenStream,
|
|
|
|
__source_path: TokenStream,
|
|
|
|
) -> TokenStream {
|
|
|
|
let local = parse_macro_input!(input as ::syn::ItemStruct);
|
|
|
|
let dep = parse_macro_input!(attrs as ::syn::ItemTrait);
|
|
|
|
|
|
|
|
let local_ident = &local.ident;
|
|
|
|
let dep_ident = parse_macro_input!(__source_path as ::syn::Path);
|
|
|
|
|
|
|
|
let mut all_deps = Vec::with_capacity(dep.items.len());
|
|
|
|
for fn_it in dep.items.iter() {
|
|
|
|
let ::syn::TraitItem::Fn(func) = fn_it else {
|
|
|
|
continue;
|
|
|
|
};
|
|
|
|
let sig = &func.sig;
|
|
|
|
let pkgbuilder_name = &sig.ident;
|
|
|
|
|
|
|
|
let builder: ::syn::ImplItemFn = ::syn::parse_quote! {
|
|
|
|
#sig {
|
|
|
|
::std::boxed::Box::new(
|
|
|
|
self.repo.#pkgbuilder_name()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
all_deps.push(builder);
|
|
|
|
}
|
|
|
|
|
|
|
|
quote! {
|
|
|
|
#local
|
|
|
|
impl #dep_ident for #local_ident {
|
|
|
|
#(#all_deps)
|
|
|
|
*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.into()
|
|
|
|
}
|