]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Add `lightning-macros` crate
authorElias Rohrer <dev@tnull.de>
Sat, 21 Sep 2024 04:51:21 +0000 (13:51 +0900)
committerElias Rohrer <dev@tnull.de>
Thu, 17 Oct 2024 14:26:41 +0000 (16:26 +0200)
Previously, we used the `bdk_macros` dependency for some simple proc
macros in `lightning-transaction-sync`. However, post-1.0 BDK doesn't
further maintain this crate and will at some point probably yank it
together with the old `bdk` crate that was split up.

Here, we create a new crate for utility proc macros and ~~steal~~ add
what we currently use (slightly modified for the latest `syn` version's
API though). In the future we may want to expand this crate, e.g., for
some `maybe_async` macros in the context of an `async KVStore`
implementation.

Cargo.toml
ci/ci-tests.sh
lightning-macros/Cargo.toml [new file with mode: 0644]
lightning-macros/src/lib.rs [new file with mode: 0644]

index add69f35afa25af26fa662ba61256d4be72e8560..f0f09f547f46384befebb6f1def81cfa564aae6d 100644 (file)
@@ -14,6 +14,7 @@ members = [
     "lightning-rapid-gossip-sync",
     "lightning-custom-message",
     "lightning-transaction-sync",
+    "lightning-macros",
     "possiblyrandom",
 ]
 
index 47f0621683c72e15309ab0f42146a3ce8f32f02b..c67f04c41e03c772c41658232e70775ef91825e3 100755 (executable)
@@ -46,6 +46,7 @@ WORKSPACE_MEMBERS=(
        lightning-rapid-gossip-sync
        lightning-custom-message
        lightning-transaction-sync
+       lightning-macros
        possiblyrandom
 )
 
diff --git a/lightning-macros/Cargo.toml b/lightning-macros/Cargo.toml
new file mode 100644 (file)
index 0000000..480d8f0
--- /dev/null
@@ -0,0 +1,26 @@
+[package]
+name = "lightning-macros"
+version = "0.1.0"
+authors = ["Elias Rohrer"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/lightningdevkit/rust-lightning/"
+description = """
+Proc macros used by LDK
+"""
+edition = "2021"
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--cfg", "docsrs"]
+
+[lib]
+proc-macro = true
+
+[features]
+
+[dependencies]
+syn = { version = "2.0.77", default-features = false, features = ["parsing", "printing", "proc-macro", "full"] }
+proc-macro2 = { version = "1.0.86", default-features = false, features = ["proc-macro"] }
+quote = { version = "1.0", default-features = false, features = ["proc-macro"] }
+
+[lints]
+workspace = true
diff --git a/lightning-macros/src/lib.rs b/lightning-macros/src/lib.rs
new file mode 100644 (file)
index 0000000..fd4707e
--- /dev/null
@@ -0,0 +1,76 @@
+// This file is Copyright its original authors, visible in version control
+// history.
+//
+// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
+// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
+// You may not use this file except in accordance with one or both of these
+// licenses.
+
+#![crate_name = "lightning_macros"]
+
+//! Proc macros used by LDK
+
+#![cfg_attr(not(test), no_std)]
+#![deny(missing_docs)]
+#![forbid(unsafe_code)]
+#![deny(rustdoc::broken_intra_doc_links)]
+#![deny(rustdoc::private_intra_doc_links)]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+use proc_macro::TokenStream;
+use quote::quote;
+use syn::spanned::Spanned;
+use syn::{parse, ImplItemFn, Token};
+
+fn add_async_method(mut parsed: ImplItemFn) -> TokenStream {
+       let output = quote! {
+               #[cfg(not(feature = "async-interface"))]
+               #parsed
+       };
+
+       parsed.sig.asyncness = Some(Token![async](parsed.span()));
+
+       let output = quote! {
+               #output
+
+               #[cfg(feature = "async-interface")]
+               #parsed
+       };
+
+       output.into()
+}
+
+/// Makes a method `async`, if the `async-interface` feature is enabled.
+#[proc_macro_attribute]
+pub fn maybe_async(_attr: TokenStream, item: TokenStream) -> TokenStream {
+       if let Ok(parsed) = parse(item) {
+               add_async_method(parsed)
+       } else {
+               (quote! {
+                       compile_error!("#[maybe_async] can only be used on methods")
+               })
+               .into()
+       }
+}
+
+/// Awaits, if the `async-interface` feature is enabled.
+#[proc_macro]
+pub fn maybe_await(expr: TokenStream) -> TokenStream {
+       let expr: proc_macro2::TokenStream = expr.into();
+       let quoted = quote! {
+               {
+                       #[cfg(not(feature = "async-interface"))]
+                       {
+                               #expr
+                       }
+
+                       #[cfg(feature = "async-interface")]
+                       {
+                               #expr.await
+                       }
+               }
+       };
+
+       quoted.into()
+}