diff libpam-sys/libpam-sys-impls/src/lib.rs @ 109:bb465393621f

Minor cleanup and reorg. - Use those nice new macros we just implemented. - Straighten out the macro file. - Move the `BinaryPayload` into `structs.rs`, leaving helpers behind.
author Paul Fisher <paul@pfish.zone>
date Sat, 28 Jun 2025 02:49:35 -0400
parents e97534be35e3
children 2346fd501b7a
line wrap: on
line diff
--- a/libpam-sys/libpam-sys-impls/src/lib.rs	Sat Jun 28 00:34:45 2025 -0400
+++ b/libpam-sys/libpam-sys-impls/src/lib.rs	Sat Jun 28 02:49:35 2025 -0400
@@ -12,26 +12,28 @@
 ///
 /// ```
 /// # use libpam_sys_impls::cfg_pam_impl;
-/// #[cfg_pam_impl("illumos")]
+/// #[cfg_pam_impl("Illumos")]
 /// fn do_something() { /* illumos-only code */ }
 ///
-/// #[cfg_pam_impl(not("illumos"))]
+/// #[cfg_pam_impl(not("Illumos"))]
 /// fn do_something() { /* non-illumos code */ }
 ///
-/// #[cfg_pam_impl(any("linux-pam", "openpam"))]
-/// fn do_something_else() { /* Linux-PAM or OpenPAM */ }
+/// #[cfg_pam_impl(any("LinuxPam", "MinimalOpenPam"))]
+/// fn do_something_else() { /* Linux-PAM or minimal OpenPAM */ }
 ///
-/// #[cfg_pam_impl(not(any("illumos", "openpam")))]
+/// #[cfg_pam_impl(not(any("Illumos", "OpenPam")))]
 /// fn do_a_third_thing() { /* Neither Illumos nor OpenPAM */ }
 ///
 /// #[cfg_pam_impl(any())]
 /// fn this_will_never_build() { /* why would you do this? */ }
+///
+/// #[cfg_pam_impl(not(any()))]
+/// fn this_will_always_build() { /* this is technically legal */ }
 /// ```
 ///
 /// [man7]: https://man7.org/linux/man-pages/man3/pam_conv.3.html
 #[proc_macro_attribute]
 pub fn cfg_pam_impl(attr: pm::TokenStream, item: pm::TokenStream) -> pm::TokenStream {
-    eprintln!("Got TokenStream: {:?}", attr);
     Predicate::parse(attr.into(), None)
         .map(|p| {
             if p.matches(pam_impl_str()) {
@@ -43,6 +45,58 @@
         .unwrap_or_else(|e| syn::Error::from(e).into_compile_error().into())
 }
 
+/// Outputs the `PamImpl` enum and `LIBPAMSYS_IMPL` constant. Private.
+#[proc_macro]
+pub fn pam_impl_enum(data: pm::TokenStream) -> pm::TokenStream {
+    if !data.is_empty() {
+        panic!("unexpected stuff in pam_impl_enum!()")
+    }
+
+    let variant = format_ident!("{}", pam_impl_str());
+
+    quote!(
+        /// The PAM implementations supported by `libpam-sys`.
+        #[non_exhaustive]
+        #[derive(Clone, Copy, Debug, PartialEq)]
+        pub enum PamImpl {
+            /// [Linux-PAM] is provided by most Linux implementations.
+            ///
+            /// [Linux-PAM]: https://github.com/linux-pam/linux-pam
+            LinuxPam,
+            /// [OpenPAM] is used by most BSD distributions, including Mac OS X.
+            ///
+            /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM
+            OpenPam,
+            /// [Illumos PAM] is used on Illumos and Solaris systems.
+            ///
+            /// [Illumos PAM]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam
+            Illumos,
+            /// Only the functionality in [the PAM spec],
+            /// with OpenPAM/Illumos constants.
+            ///
+            /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm
+            MinimalOpenPam,
+        }
+
+        #[doc = concat!("This version of libpam-sys was built for **", stringify!(#variant), "**.")]
+        pub const LIBPAMSYS_IMPL: PamImpl = PamImpl::#variant;
+    )
+    .into()
+}
+
+/// The name of the PAM implementation. Used only in `libpam-sys`. Private.
+#[proc_macro]
+pub fn pam_impl_name(data: pm::TokenStream) -> pm::TokenStream {
+    if !data.is_empty() {
+        panic!("pam_impl_name! does not take any input")
+    }
+    pm::TokenTree::Literal(pm::Literal::string(pam_impl_str())).into()
+}
+
+fn pam_impl_str() -> &'static str {
+    env!("LIBPAMSYS_IMPL")
+}
+
 #[derive(Debug)]
 enum Error {
     WithSpan(syn::Error),
@@ -93,9 +147,7 @@
         match self {
             Self::Literal(literal) => value == literal,
             Self::Not(pred) => !pred.matches(value),
-            Self::Any(options) => {
-                options.iter().any(|s| s == value)
-            }
+            Self::Any(options) => options.iter().any(|s| s == value),
         }
     }
 
@@ -144,9 +196,9 @@
                 Some(TokenTree::Literal(lit)) => {
                     output.push(Self::string_lit(lit)?);
                     if !maybe_comma(iter.next())? {
-                        break
+                        break;
                     }
-                },
+                }
                 Some(other) => return unexpected(&other, "string literal"),
             }
         }
@@ -187,57 +239,6 @@
     }
 }
 
-/// A proc macro that outputs the PAM implementation macro and const.
-#[proc_macro]
-pub fn pam_impl_enum(data: pm::TokenStream) -> pm::TokenStream {
-    if !data.is_empty() { panic!("unexpected stuff in pam_impl_enum!()") }
-
-    let variant = format_ident!("{}", pam_impl_str());
-
-    quote!(
-        /// The PAM implementations supported by `libpam-sys`.
-        #[non_exhaustive]
-        #[derive(Clone, Copy, Debug, PartialEq)]
-        pub enum PamImpl {
-            /// [Linux-PAM] is provided by most Linux implementations.
-            /// 
-            /// [Linux-PAM]: https://github.com/linux-pam/linux-pam
-            LinuxPam,
-            /// [OpenPAM] is used by most BSD distributions, including Mac OS X.
-            /// 
-            /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM
-            OpenPam,
-            /// [Illumos PAM] is used on Illumos and Solaris systems.
-            ///
-            /// [Illumos PAM]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam
-            Illumos,
-            /// Only the functionality in [the PAM spec],
-            /// with OpenPAM/Illumos constants.
-            /// 
-            /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm
-            MinimalOpenPam,
-        }
-
-        #[doc = concat!("This version of libpam-sys was built for **", stringify!(#variant), "**.")]
-        pub const LIBPAMSYS_IMPL: PamImpl = PamImpl::#variant;
-    ).into()
-}
-
-/// String literal of the name of the PAM implementation this was built for.
-///
-/// The value is the string value of `libpamsys::PamImpl`.
-#[proc_macro]
-pub fn pam_impl_name(data: pm::TokenStream) -> pm::TokenStream {
-    if !data.is_empty() {
-        panic!("pam_impl_name! does not take any input")
-    }
-    pm::TokenTree::Literal(pm::Literal::string(pam_impl_str())).into()
-}
-
-fn pam_impl_str() -> &'static str {
-    env!("LIBPAMSYS_IMPL")
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -296,7 +297,9 @@
         }
         let matching = cases![
             ("Illumos", (any("Illumos", "OpenPam"))),
+            ("OpenPam", (any("Illumos", "OpenPam"))),
             ("LinuxPam", (not("OpenPam"))),
+            ("MinimalOpenPam", (not("OpenPam"))),
             ("Other", (not(any("This", "That")))),
             ("OpenPam", (not(not("OpenPam")))),
             ("Anything", (not(any()))),