Mercurial > crates > nonstick
diff libpam-sys/libpam-sys-helpers/src/pam_impl.rs @ 136:efbc235f01d3
Separate libpam-sys-helpers from libpam-sys.
This separates the parts of libpam-sys that don't need linking against libpam
from the parts that do need to link against libpam.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 03 Jul 2025 14:28:04 -0400 |
parents | libpam-sys/src/pam_impl.rs@6c1e1bdb4164 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpam-sys/libpam-sys-helpers/src/pam_impl.rs Thu Jul 03 14:28:04 2025 -0400 @@ -0,0 +1,113 @@ +// This file is include!d directly by `../build.rs`, so its doc comment +// is found in lib.rs. + +/// An enum that knows its own values. +macro_rules! self_aware_enum { + ( + $(#[$enumeta:meta])* + $viz:vis enum $name:ident { + $( + $(#[$itemeta:meta])* + $item:ident, + )* + } + ) => { + $(#[$enumeta])* + $viz enum $name { + $( + $(#[$itemeta])* + $item, + )* + } + + // The implementations in this block are private for now + // to avoid putting a contract into the public API. + #[allow(dead_code)] + impl $name { + /// Iterator over the items in the enum. For internal use. + fn items() -> Vec<Self> { + vec![$(Self::$item),*] + } + + /// Attempts to parse the enum from the string. For internal use. + fn try_from(value: &str) -> Result<Self, String> { + match value { + $(stringify!($item) => Ok(Self::$item),)* + _ => Err(value.into()), + } + } + } + }; +} + +self_aware_enum! { + /// The PAM implementations supported by `libpam-sys`. + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + #[cfg_attr(pam_impl, non_exhaustive)] + pub enum PamImpl { + /// [Linux-PAM] is provided by most Linux distributions. + /// + /// [Linux-PAM]: https://github.com/linux-pam/linux-pam + LinuxPam, + /// [OpenPAM] is used by most BSDs, including Mac OS X. + /// + /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM + OpenPam, + /// Illumos and Solaris use a derivative of [Sun's implementation][sun]. + /// + /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam + Sun, + /// Only the functionality and constants in [the PAM spec]. + /// + /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm + XSso, + } +} + +// This generated file contains: +// - pam_impl_name! +// - PamImpl::CURRENT +#[cfg(pam_impl)] +include!(concat!(env!("OUT_DIR"), "/pam_impl_const.rs")); + +#[allow(clippy::needless_doctest_main)] +/// Generates `cargo` directives for build scripts to enable `cfg(pam_impl)`. +/// +/// Print this in your `build.rs` script to be able to use the custom `pam_impl` +/// configuration directive. +/// +/// ``` +/// // build.rs +/// use libpam_sys_helpers::pam_impl; +/// fn main() { +/// pam_impl::enable_pam_impl_cfg(); +/// +/// // Whatever other stuff you do in your build.rs. +/// } +/// ``` +#[cfg(pam_impl)] +pub fn enable_pam_impl_cfg() { + println!("{}", pam_impl_cfg_string()) +} + +/// Generates the `cargo:` directives to print in build scripts. +#[cfg(pam_impl)] +pub fn pam_impl_cfg_string() -> String { + generate_cfg(pam_impl_name!()) +} + +fn generate_cfg(name: &str) -> String { + let impls: Vec<_> = PamImpl::items() + .into_iter() + .map(|i| format!(r#""{i:?}""#)) + .collect(); + format!( + "\ +cargo:rustc-check-cfg=cfg(pam_impl) +cargo:rustc-check-cfg=cfg(pam_impl, values({impls})) +cargo:rustc-cfg=pam_impl +cargo:rustc-cfg=pam_impl={name:?} + ", + impls = impls.join(",") + ) +}