comparison libpam-sys/libpam-sys-impls/src/pam_impl.rs @ 176:0730f5f2ee2a

Turn `libpam-sys-consts` back into `libpam-sys-impls`. This moves the constants into `libpam-sys` and makes `libpam-sys-impls` responsible solely for detecting the current PAM implementation.
author Paul Fisher <paul@pfish.zone>
date Wed, 30 Jul 2025 17:53:31 -0400
parents libpam-sys/libpam-sys-consts/src/pam_impl.rs@4b3a5095f68c
children
comparison
equal deleted inserted replaced
175:e30775c80b49 176:0730f5f2ee2a
1 // This file is include!d directly by `../build.rs`, so its doc comment
2 // is found in lib.rs.
3
4 /// An enum that knows its own values.
5 macro_rules! self_aware_enum {
6 (
7 $(#[$enumeta:meta])*
8 $viz:vis enum $name:ident {
9 $(
10 $(#[$itemeta:meta])*
11 $item:ident,
12 )*
13 }
14 ) => {
15 $(#[$enumeta])*
16 $viz enum $name {
17 $(
18 $(#[$itemeta])*
19 $item,
20 )*
21 }
22
23 // The implementations in this block are private for now
24 // to avoid putting a contract into the public API.
25 #[allow(dead_code)]
26 impl $name {
27 /// Iterator over the items in the enum. For internal use.
28 fn items() -> Vec<Self> {
29 vec![$(Self::$item),*]
30 }
31
32 /// Attempts to parse the enum from the string. For internal use.
33 fn try_from(value: &str) -> Result<Self, String> {
34 match value {
35 $(stringify!($item) => Ok(Self::$item),)*
36 _ => Err(value.into()),
37 }
38 }
39 }
40 };
41 }
42
43 self_aware_enum! {
44 /// The PAM implementations supported by `libpam-sys`.
45 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
46 #[cfg_attr(pam_impl, non_exhaustive)]
47 pub enum PamImpl {
48 /// [Linux-PAM] is provided by most Linux distributions.
49 ///
50 /// [Linux-PAM]: https://github.com/linux-pam/linux-pam
51 LinuxPam,
52 /// [OpenPAM] is used by most BSDs, including Mac OS X.
53 ///
54 /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM
55 OpenPam,
56 /// Illumos and Solaris use a derivative of [Sun's implementation][sun].
57 ///
58 /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam
59 Sun,
60 /// Only the functionality and constants in [the PAM spec].
61 ///
62 /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm
63 XSso,
64 }
65 }
66
67 // This generated file contains:
68 // - pam_impl_name!
69 // - PamImpl::CURRENT
70 #[cfg(pam_impl)]
71 include!(concat!(env!("OUT_DIR"), "/pam_impl_const.rs"));
72
73 #[allow(clippy::needless_doctest_main)]
74 /// Generates `cargo` directives for build scripts to enable `cfg(pam_impl)`.
75 ///
76 /// Print this in your `build.rs` script to be able to use the custom `pam_impl`
77 /// configuration directive.
78 ///
79 /// ```
80 /// // build.rs
81 /// fn main() {
82 /// libpam_sys_impls::enable_pam_impl_cfg();
83 ///
84 /// // Whatever other stuff you do in your build.rs.
85 /// }
86 /// ```
87 #[cfg(pam_impl)]
88 pub fn enable_pam_impl_cfg() {
89 println!("{}", pam_impl_cfg_string())
90 }
91
92 /// Generates the `cargo:` directives to print in build scripts.
93 #[cfg(pam_impl)]
94 pub fn pam_impl_cfg_string() -> String {
95 generate_cfg(pam_impl_name!())
96 }
97
98 fn generate_cfg(name: &str) -> String {
99 let impls: Vec<_> = PamImpl::items()
100 .into_iter()
101 .map(|i| format!(r#""{i:?}""#))
102 .collect();
103 format!(
104 "\
105 cargo:rustc-check-cfg=cfg(pam_impl)
106 cargo:rustc-check-cfg=cfg(pam_impl, values({impls}))
107 cargo:rustc-cfg=pam_impl
108 cargo:rustc-cfg=pam_impl={name:?}
109 ",
110 impls = impls.join(",")
111 )
112 }