Display a package
Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
parent
1d9ea5a699
commit
11ecc75393
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -35,8 +35,10 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bok",
|
||||
"bok-macro",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -45,6 +47,16 @@ version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
|
@ -101,7 +101,7 @@ pub fn derive_repository(input: TokenStream) -> TokenStream {
|
||||
/// e.g.:
|
||||
/// ```
|
||||
/// impl MyPackage {
|
||||
/// #[package(::bok_macro::to_code)]
|
||||
/// #[::bok_macro::to_code]
|
||||
/// fn build() {
|
||||
/// ...
|
||||
/// }
|
||||
@ -216,6 +216,7 @@ pub fn package(attrs: TokenStream, input: TokenStream) -> TokenStream {
|
||||
#[proc_macro_derive(Package)]
|
||||
pub fn derive_package(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
let input2 = input.clone();
|
||||
|
||||
let name = input.ident.clone();
|
||||
let name_builder = quote::format_ident!("{name}Builder");
|
||||
@ -355,20 +356,76 @@ pub fn derive_package(input: TokenStream) -> TokenStream {
|
||||
let opt_types2 = opt_types.clone();
|
||||
let non_opt_types2 = non_opt_types.clone();
|
||||
|
||||
let expanded = quote! {
|
||||
let impl_base = quote! {
|
||||
impl ::bok::Pkg for #name {
|
||||
fn base(&self) -> Option<&impl ::bok::Pkg> {
|
||||
Some(&self.base)
|
||||
}
|
||||
}
|
||||
// FIXME: proper formatting of all functions
|
||||
};
|
||||
|
||||
let pkg_struct = quote! {
|
||||
#input2
|
||||
};
|
||||
let mut pkg_struct_str = String::new();
|
||||
{
|
||||
use ::core::fmt::Write;
|
||||
write!(&mut pkg_struct_str, "{}", pkg_struct)
|
||||
.expect("can't write package struct into string");
|
||||
}
|
||||
|
||||
let expanded = quote! {
|
||||
#impl_base
|
||||
|
||||
impl ::core::fmt::Display for #name {
|
||||
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>)
|
||||
->::core::fmt::Result
|
||||
{
|
||||
// FIXME: this sounds convoluted.
|
||||
// first we make everything into a string, then we
|
||||
// parse the string into tokenstream again to format it
|
||||
// reason: the `prettyplease` works on `::syn::File`
|
||||
// and I can't find an easy translation
|
||||
// `TokenStream2 -> TokenStream`
|
||||
use ::bok::Pkg;
|
||||
let pkg = self.package_code();
|
||||
pkg.fmt(f)
|
||||
|
||||
// don't add a method if it is just the base Trait implementation
|
||||
fn maybe_add_fn(out: &mut String, name: &str, fn_str: &str) -> ::core::fmt::Result {
|
||||
|
||||
let str_base = "self . base () . unwrap () . ".to_owned() + name + " ()";
|
||||
|
||||
if fn_str.trim() != str_base {
|
||||
use ::core::fmt::Write;
|
||||
|
||||
write!(out,
|
||||
"#[::bok_macro::to_code]\n\
|
||||
fn {}(&self) -> Result<(), ()> {{\n{}\n}}\n",
|
||||
name, fn_str)
|
||||
|
||||
} else {
|
||||
::core::fmt::Result::Ok(())
|
||||
}
|
||||
};
|
||||
|
||||
// from the Pkg trait
|
||||
use ::core::fmt::Write;
|
||||
|
||||
let pkg_empty = ::bok::PkgEmpty{};
|
||||
let mut pkg_string = String::new();
|
||||
write!(&mut pkg_string, "{}", #pkg_struct_str)?;
|
||||
write!(&mut pkg_string,
|
||||
"impl ::bok::Pkg for {} {{\n",
|
||||
::std::stringify!(#name)
|
||||
)?;
|
||||
maybe_add_fn(&mut pkg_string, "prepare", &self.prepare_code().to_string())?;
|
||||
maybe_add_fn(&mut pkg_string, "configure", &self.configure_code().to_string())?;
|
||||
maybe_add_fn(&mut pkg_string, "build", &self.build_code().to_string())?;
|
||||
maybe_add_fn(&mut pkg_string, "check", &self.check_code().to_string())?;
|
||||
maybe_add_fn(&mut pkg_string, "install", &self.install_code().to_string())?;
|
||||
write!(&mut pkg_string, "}}\n")?;
|
||||
let re_parsed = ::syn::parse_file(&pkg_string).unwrap();
|
||||
let formatted = prettyplease::unparse(&re_parsed);
|
||||
f.write_str(&formatted)
|
||||
}
|
||||
}
|
||||
impl #name {
|
||||
|
@ -16,3 +16,5 @@ bok = { path = "../bok" }
|
||||
bok-macro = { path = "../bok-macro" }
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
prettyplease = "0.2"
|
||||
syn = { version = "2", features = [ "full", "parsing" ] }
|
||||
|
@ -1,9 +1,9 @@
|
||||
/*
|
||||
* 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
|
||||
* 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
|
||||
@ -27,4 +27,6 @@ fn main() {
|
||||
println!("pkgs2 - 1:{}", pkgs2.one().my_attr);
|
||||
println!("pkgs2 - 2:{}", pkgs2.two().my_attr);
|
||||
println!("pkgs2 - 3:{}", pkgs2.three().my_attr);
|
||||
|
||||
println!("pkgs1:\n{}", pkgs1.one());
|
||||
}
|
||||
|
@ -131,15 +131,6 @@ pub trait Pkg: ::std::default::Default + ::core::fmt::Display {
|
||||
self.check()?;
|
||||
self.install()
|
||||
}
|
||||
fn package_code(&self) -> ::proc_macro2::TokenStream {
|
||||
::quote::quote! {
|
||||
self.prepare()?;
|
||||
self.configure()?;
|
||||
self.build()?;
|
||||
self.check()?;
|
||||
self.install()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
Loading…
Reference in New Issue
Block a user