From 11ecc75393d98d776b3be62a6124af3c14183f4e Mon Sep 17 00:00:00 2001 From: Luca Fulchir Date: Wed, 27 Mar 2024 11:34:09 +0100 Subject: [PATCH] Display a package Signed-off-by: Luca Fulchir --- Cargo.lock | 12 ++++++++ bok-macro/src/lib.rs | 67 +++++++++++++++++++++++++++++++++++++++---- bok-utils/Cargo.toml | 2 ++ bok-utils/src/main.rs | 8 ++++-- bok/src/lib.rs | 9 ------ 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa9338c..6d00e5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/bok-macro/src/lib.rs b/bok-macro/src/lib.rs index 937e979..d6028af 100644 --- a/bok-macro/src/lib.rs +++ b/bok-macro/src/lib.rs @@ -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 { diff --git a/bok-utils/Cargo.toml b/bok-utils/Cargo.toml index d8c2064..8346407 100644 --- a/bok-utils/Cargo.toml +++ b/bok-utils/Cargo.toml @@ -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" ] } diff --git a/bok-utils/src/main.rs b/bok-utils/src/main.rs index 9b79e7f..d42dbcf 100644 --- a/bok-utils/src/main.rs +++ b/bok-utils/src/main.rs @@ -1,9 +1,9 @@ /* * Copyright 2024 Luca Fulchir * - * 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()); } diff --git a/bok/src/lib.rs b/bok/src/lib.rs index 56a6caa..b4cdb34 100644 --- a/bok/src/lib.rs +++ b/bok/src/lib.rs @@ -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)]