]> git.proxmox.com Git - perlmod.git/commitdiff
fix #[export(name=...)], drop deprecated make_package
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 25 Nov 2020 13:35:34 +0000 (14:35 +0100)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 25 Nov 2020 13:35:34 +0000 (14:35 +0100)
The `make_package` macro is tedious to use. We now simply
depend on new-enough rustc for `package` to work.

The change to #[export] allows writing:

    #[export(name = "DESTROY")]
    fn destroy(#[raw] this: Value) { ... }

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
perlmod-macro/src/attribs.rs
perlmod-macro/src/function.rs
perlmod-macro/src/lib.rs
perlmod-macro/src/module.rs
perlmod-macro/src/package.rs
perlmod-test/src/bless.rs
perlmod-test/src/lib.rs
perlmod-test/src/pkgstable.rs [deleted file]
perlmod/src/lib.rs
perlmod/src/scalar.rs

index 34b55e0de27fe474d474c0c34b21f5528e40d182..7c77fabcff9cf3be831d48df30980c0431f0f557 100644 (file)
@@ -64,7 +64,9 @@ impl ModuleAttrs {
     }
 }
 
+#[derive(Default)]
 pub struct FunctionAttrs {
+    pub perl_name: Option<Ident>,
     pub xs_name: Option<Ident>,
     pub raw_return: bool,
 }
@@ -73,8 +75,7 @@ impl TryFrom<AttributeArgs> for FunctionAttrs {
     type Error = syn::Error;
 
     fn try_from(args: AttributeArgs) -> Result<Self, Self::Error> {
-        let mut xs_name = None;
-        let mut raw_return = false;
+        let mut attrs = FunctionAttrs::default();
 
         for arg in args {
             match arg {
@@ -83,15 +84,17 @@ impl TryFrom<AttributeArgs> for FunctionAttrs {
                     lit: syn::Lit::Str(litstr),
                     ..
                 })) => {
-                    if path.is_ident("name") {
-                        xs_name = Some(Ident::new(&litstr.value(), litstr.span()));
+                    if path.is_ident("xs_name") {
+                        attrs.xs_name = Some(Ident::new(&litstr.value(), litstr.span()));
+                    } else if path.is_ident("name") {
+                        attrs.perl_name = Some(Ident::new(&litstr.value(), litstr.span()));
                     } else {
                         bail!(path => "unknown argument");
                     }
                 }
                 syn::NestedMeta::Meta(syn::Meta::Path(path)) => {
                     if path.is_ident("raw_return") {
-                        raw_return = true;
+                        attrs.raw_return = true;
                     } else {
                         bail!(path => "unknown attribute");
                     }
@@ -100,9 +103,6 @@ impl TryFrom<AttributeArgs> for FunctionAttrs {
             }
         }
 
-        Ok(Self {
-            xs_name,
-            raw_return,
-        })
+        Ok(attrs)
     }
 }
index c5c8d2a26ac83ee34c37e5c516cdb0e5a4bc8fa5..a845ad6a09c695ab0db517de9425cfcc6a123ac0 100644 (file)
@@ -8,6 +8,7 @@ use crate::attribs::FunctionAttrs;
 
 pub struct XSub {
     pub rust_name: Ident,
+    pub perl_name: Option<Ident>,
     pub xs_name: Ident,
     pub tokens: TokenStream,
 }
@@ -201,6 +202,7 @@ pub fn handle_function(
         #wrapper_func
 
         #[inline(never)]
+        #[allow(non_snake_case)]
         fn #impl_xs_name(
             _cv: &::perlmod::ffi::CV,
         ) -> Result<#return_type, *mut ::perlmod::ffi::SV> {
@@ -229,6 +231,7 @@ pub fn handle_function(
 
     Ok(XSub {
         rust_name: name.to_owned(),
+        perl_name: attr.perl_name.clone(),
         xs_name,
         tokens,
     })
index 64ec05bab99dd470c2516f2d5fd8e8c494646bd6..045e33a1468704b218eecea1bf28d7b40e41651a 100644 (file)
@@ -74,7 +74,7 @@ pub fn package(attr: TokenStream_1, item: TokenStream_1) -> TokenStream_1 {
 }
 
 /// Attribute to export a function so that it can be installed as an `xsub` in perl. See the
-/// [`make_package!`] macro for a usage example.
+/// [`package!`] macro for a usage example.
 #[proc_macro_attribute]
 pub fn export(attr: TokenStream_1, item: TokenStream_1) -> TokenStream_1 {
     let attr = parse_macro_input!(attr as AttributeArgs);
@@ -82,68 +82,6 @@ pub fn export(attr: TokenStream_1, item: TokenStream_1) -> TokenStream_1 {
     handle_error(item.clone(), export_impl(attr, item)).into()
 }
 
-/// Proc macro to create a perl package file for rust functions.
-///
-/// This macro will write a perl package/module file into cargo's working directory. (Typically the
-/// manifest directory.)
-///
-/// This macro exists mostly for backward compatibility. When using rustc 1.42 or above, a more
-/// readable and less repetitive code will be produced with the [`package`](module@crate::package)
-/// attribute instead.
-///
-/// This macro always has to be used in conjunction with the [`export!]` macro, like this:
-///
-/// ```
-/// # mod testmod {
-/// use anyhow::{bail, Error};
-/// use perlmod::export;
-///
-/// #[export]
-/// fn sum_except_42(a: u32, b: u32) -> Result<u32, Error> {
-///     if a == 42 {
-///         // Errors 'die' in perl, so newlines at the end of error messages make a difference!
-///         bail!("dying on magic number\n");
-///     }
-///
-///     Ok(a + b)
-/// }
-///
-/// #[export(name = "xs_sub_name")]
-/// fn double(a: u32) -> Result<u32, Error> {
-///     Ok(2 * a)
-/// }
-///
-/// perlmod::make_package! {
-///     // First we need to specify the package, similar to perl's syntax:
-///     package "RSPM::DocTest1";
-///
-///     // The library name is usually derived from the crate name in Cargo.toml automatically.
-///     // So this line is optional:
-///     lib "perlmod_test";
-///
-///     // An optional output file name can be specified as follows:
-///     // (we use this here to prevent doc tests from creating files...)
-///     file "/dev/null";
-///
-///     // The list of xsubs we want to export:
-///     subs {
-///         // When only providing the name, default naming convention will be used:
-///         // This is used like: `RSPM::DocTest1::sum_except_42(4, 5);` in perl.
-///         sum_except_42,
-///         // If we used an explicit export name, we need to also explicitly export the renamed
-///         // function here:
-///         // This is used like: `RSPM::DocTest1::double_the_number(5);` in perl.
-///         xs_sub_name as double_the_number,
-///     }
-/// }
-/// # }
-/// ```
-#[proc_macro]
-pub fn make_package(item: TokenStream_1) -> TokenStream_1 {
-    let item: TokenStream = item.into();
-    handle_error(item.clone(), make_package_impl(item)).into()
-}
-
 fn perlmod_impl(attr: AttributeArgs, item: TokenStream) -> Result<TokenStream, Error> {
     let item: syn::Item = syn::parse2(item)?;
 
@@ -161,9 +99,3 @@ fn export_impl(attr: AttributeArgs, item: TokenStream) -> Result<TokenStream, Er
     let func = function::handle_function(attr, func, None)?;
     Ok(func.tokens)
 }
-
-fn make_package_impl(item: TokenStream) -> Result<TokenStream, Error> {
-    let pkg: package::Package = syn::parse2(item)?;
-    pkg.write()?;
-    Ok(TokenStream::new())
-}
index bb4bb902dd202388b91aee5c254b685dd3cdfd57..f3aae4c88db4052ee6ce3d9af2559e17559a45c2 100644 (file)
@@ -55,6 +55,7 @@ pub fn handle_module(attr: AttributeArgs, mut module: syn::ItemMod) -> Result<To
 
                         package.export_named(
                             func.rust_name,
+                            func.perl_name,
                             func.xs_name,
                             "src/FIXME.rs".to_string(),
                         );
index d0ade27f4ca368fcf2008b41eb359c8c0a260e9b..9f4afe0b7d5eaa1f905cb7ad38e80cff2bbc6c21 100644 (file)
@@ -8,10 +8,7 @@ use anyhow::Error;
 
 use proc_macro2::{Ident, Span};
 
-use syn::parse::Parse;
-use syn::punctuated::Punctuated;
 use syn::AttributeArgs;
-use syn::Token;
 
 use toml::Value;
 
@@ -56,6 +53,7 @@ const MODULE_TAIL: &str = "}\n";
 
 struct Export {
     rust_name: Ident,
+    perl_name: Option<Ident>,
     xs_name: Ident,
     file_name: String,
 }
@@ -73,18 +71,16 @@ impl Package {
         })
     }
 
-    pub fn export_named(&mut self, rust_name: Ident, xs_name: Ident, file_name: String) {
+    pub fn export_named(
+        &mut self,
+        rust_name: Ident,
+        perl_name: Option<Ident>,
+        xs_name: Ident,
+        file_name: String,
+    ) {
         self.exported.push(Export {
             rust_name,
-            xs_name,
-            file_name,
-        });
-    }
-
-    pub fn export_direct(&mut self, name: Ident, file_name: String) {
-        let xs_name = Ident::new(&format!("xs_{}", name), name.span());
-        self.exported.push(Export {
-            rust_name: name,
+            perl_name,
             xs_name,
             file_name,
         });
@@ -97,7 +93,7 @@ impl Package {
             source = format!(
                 "{}    newXS('{}', '{}', \"{}\");\n",
                 source,
-                export.rust_name,
+                export.perl_name.as_ref().unwrap_or(&export.rust_name),
                 export.xs_name,
                 export.file_name.replace('"', "\\\""),
             );
@@ -132,88 +128,6 @@ impl Package {
     }
 }
 
-mod kw {
-    syn::custom_keyword!(package);
-    syn::custom_keyword!(lib);
-    syn::custom_keyword!(file);
-    syn::custom_keyword!(subs);
-}
-
-impl Parse for Package {
-    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
-        let mut pkg = Package {
-            attrs: ModuleAttrs {
-                package_name: String::new(),
-                file_name: None,
-                lib_name: None,
-            },
-            exported: Vec::new(),
-        };
-
-        // `package "Package::Name";` comes first
-        let _pkg: kw::package = input.parse()?;
-        let package: syn::LitStr = input.parse()?;
-        let _semicolon: Token![;] = input.parse()?;
-        pkg.attrs.package_name = package.value();
-
-        // `lib "lib_name";` optionally comes second
-        let lookahead = input.lookahead1();
-        if lookahead.peek(kw::lib) {
-            let _lib: kw::lib = input.parse()?;
-            let lib: syn::LitStr = input.parse()?;
-            pkg.attrs.lib_name = Some(lib.value());
-            let _semicolon: Token![;] = input.parse()?;
-        }
-        drop(lookahead);
-
-        // `file "File/Name.pm";` optionally comes third
-        let lookahead = input.lookahead1();
-        if lookahead.peek(kw::file) {
-            let _file: kw::file = input.parse()?;
-            let file: syn::LitStr = input.parse()?;
-            pkg.attrs.file_name = Some(file.value());
-            let _semicolon: Token![;] = input.parse()?;
-        }
-        drop(lookahead);
-
-        // `sub { ... }` must follow:
-        let _sub: kw::subs = input.parse()?;
-        let content;
-        let _brace_token: syn::token::Brace = syn::braced!(content in input);
-        let items: Punctuated<ExportItem, Token![,]> =
-            content.parse_terminated(ExportItem::parse)?;
-
-        for item in items {
-            match item {
-                ExportItem::Direct(name) => pkg.export_direct(name, "src/FIXME.rs".to_string()),
-                ExportItem::Named(name, as_name) => {
-                    pkg.export_named(as_name, name, "src/FIXME.rs".to_string());
-                }
-            }
-        }
-
-        Ok(pkg)
-    }
-}
-
-enum ExportItem {
-    Direct(Ident),
-    Named(Ident, Ident),
-}
-
-impl Parse for ExportItem {
-    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
-        let name: Ident = input.parse()?;
-        let lookahead = input.lookahead1();
-        if lookahead.peek(syn::token::As) {
-            let _as: syn::token::As = input.parse()?;
-            Ok(ExportItem::Named(name, input.parse()?))
-        } else {
-            Ok(ExportItem::Direct(name))
-        }
-    }
-}
-
 fn read_cargo_toml(why: Span) -> Result<HashMap<String, Value>, syn::Error> {
     let manifest_dir = env::var("CARGO_MANIFEST_DIR")
         .map_err(|err| format_err!(why, "failed to get CARGO_MANIFEST_DIR variable: {}", err))?;
index e79ed378016751921b111b32e236a50f634eff57..c97393878e5e57cf0042822016a50c0cbf873801 100644 (file)
@@ -26,8 +26,8 @@ mod export {
         println!("Called something!");
     }
 
-    #[export]
-    fn DESTROY(#[raw] this: Value) {
+    #[export(name = "DESTROY")]
+    fn destroy(#[raw] this: Value) {
         match this
             .dereference()
             .ok_or_else(|| format_err!("not a reference"))
index a10c2e894e9dd62b08c161008af71d4ce818ee02..9935a8d39daa10041ed9f15d33b78dbd051ec5f4 100644 (file)
@@ -7,8 +7,5 @@ mod pkg142;
 /// possible on nightly with #![feature(custom_inner_attributes)]
 mod pkginline;
 
-/// This is possible on stable rust with some 1.3x already.
-mod pkgstable;
-
 /// A test for blessed values.
 mod bless;
diff --git a/perlmod-test/src/pkgstable.rs b/perlmod-test/src/pkgstable.rs
deleted file mode 100644 (file)
index 1ecfafc..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-use anyhow::{bail, Error};
-
-#[perlmod::export]
-fn foo(a: u32, b: u32) -> Result<u32, Error> {
-    if a == 42 {
-        bail!("dying on magic number");
-    }
-
-    Ok(a + b)
-}
-
-#[perlmod::export(name = "xs_a")]
-fn func_b(a: u32) -> Result<u32, Error> {
-    Ok(a * 2)
-}
-
-perlmod::make_package! {
-    package "RSPM::Foo";
-
-    //lib "perlmod_test";
-
-    subs {
-        foo,
-        xs_a as b, // func_b's exported xsub was renamed to xs_a, and in perl it's called b
-    }
-}
index d7b3aa0e121fdfd58fb029a3b162855dea4db33e..e5211eba740387eefb277160d53e420aabd60f5f 100644 (file)
@@ -1,17 +1,13 @@
 //! Crate for creating perl packages/bindings for rust code.
 //!
-//! The main feature of this crate are the [`package`], [`export`] and [`make_package!`] macros
-//! provided by the `perlmod-macro` crate. These are documented here.
+//! The main feature of this crate is the [`package`] macro provided by the `perlmod-macro` crate
+//! and documented here.
 //!
 //! The underlying machinery for these macros is contained in this crate and provides ways to
 //! serialize and deserialize data between perl and rust.
 //!
-//! For now, see the [`make_package!`] macro for all the details, since as of the time of writing
-//! this, we're only at rust 1.40.
-//!
 //! [`package`]: attr.package.html
 //! [`export`]: attr.export.html
-//! [`make_package!`]: macro.make_package.html
 
 pub(crate) mod error;
 pub use error::Error;
@@ -43,4 +39,4 @@ pub use value::Value;
 
 #[cfg(feature = "exporter")]
 #[doc(inline)]
-pub use perlmod_macro::{export, make_package, package};
+pub use perlmod_macro::{export, package};
index bbd7f9300642f94d4a0798c505491c847c1e9549..49705b7d576944dd2196b894f699bcb8efddc4bc 100644 (file)
@@ -272,7 +272,7 @@ impl ScalarRef {
     ///
     /// The user is responsible for making sure the underlying pointer is correct.
     pub unsafe fn pv_ref<T>(&self) -> Result<&T, Error> {
-        self.pv_raw().map(|p| unsafe { &*p })
+        self.pv_raw().map(|p| &*p)
     }
 
     /// Interpret the byte string as a pointer and return it as a mutable reference for
@@ -282,7 +282,7 @@ impl ScalarRef {
     ///
     /// The user is responsible for making sure the underlying pointer is correct.
     pub unsafe fn pv_mut_ref<T>(&self) -> Result<&mut T, Error> {
-        self.pv_raw().map(|p| unsafe { &mut *p })
+        self.pv_raw().map(|p| &mut *p)
     }
 
     /// Create another owned reference to this value.