Mercurial > crates > nonstick
comparison libpam-sys/src/pam_impl.rs @ 134:6c1e1bdb4164
Use standard #[cfg] directives rather than custom proc macros.
Instead of having to do a bunch of custom parsing and other logic
that tools often choke on, this change introduces an easy way
to depend upon custom #[cfg]s provided by the libpam-sys crate.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Thu, 03 Jul 2025 11:03:36 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
133:32b2a545ca3e | 134:6c1e1bdb4164 |
---|---|
1 /// An enum that knows its own values. | |
2 macro_rules! self_aware_enum { | |
3 ( | |
4 $(#[$enumeta:meta])* | |
5 $viz:vis enum $name:ident { | |
6 $( | |
7 $(#[$itemeta:meta])* | |
8 $item:ident, | |
9 )* | |
10 } | |
11 ) => { | |
12 $(#[$enumeta])* | |
13 $viz enum $name { | |
14 $( | |
15 $(#[$itemeta])* | |
16 $item, | |
17 )* | |
18 } | |
19 | |
20 // The implementations in this block are private for now | |
21 // to avoid putting a contract into the public API. | |
22 #[allow(dead_code)] | |
23 impl $name { | |
24 /// Iterator over the items in the enum. For internal use. | |
25 fn items() -> Vec<Self> { | |
26 vec![$(Self::$item),*] | |
27 } | |
28 | |
29 /// Attempts to parse the enum from the string. For internal use. | |
30 fn try_from(value: &str) -> Result<Self, String> { | |
31 match value { | |
32 $(stringify!($item) => Ok(Self::$item),)* | |
33 _ => Err(value.into()), | |
34 } | |
35 } | |
36 } | |
37 }; | |
38 } | |
39 | |
40 self_aware_enum! { | |
41 /// The PAM implementations supported by `libpam-sys`. | |
42 #[derive(Clone, Copy, Debug, PartialEq, Eq)] | |
43 #[cfg_attr(pam_impl, non_exhaustive)] | |
44 pub enum PamImpl { | |
45 /// [Linux-PAM] is provided by most Linux distributions. | |
46 /// | |
47 /// [Linux-PAM]: https://github.com/linux-pam/linux-pam | |
48 LinuxPam, | |
49 /// [OpenPAM] is used by most BSDs, including Mac OS X. | |
50 /// | |
51 /// [OpenPAM]: https://git.des.dev/OpenPAM/OpenPAM | |
52 OpenPam, | |
53 /// Illumos and Solaris use a derivative of [Sun's implementation][sun]. | |
54 /// | |
55 /// [sun]: https://code.illumos.org/plugins/gitiles/illumos-gate/+/refs/heads/master/usr/src/lib/libpam | |
56 Sun, | |
57 /// Only the functionality and constants in [the PAM spec]. | |
58 /// | |
59 /// [the PAM spec]: https://pubs.opengroup.org/onlinepubs/8329799/toc.htm | |
60 XSso, | |
61 } | |
62 } | |
63 | |
64 #[cfg(pam_impl)] | |
65 include!(concat!(env!("OUT_DIR"), "/pam_impl_const.rs")); | |
66 | |
67 /// Generates `cargo` directives for build scripts to enable `cfg(pam_impl)`. | |
68 /// | |
69 /// Print this in your `build.rs` script to be able to use the custom `pam_impl` | |
70 /// configuration directive. | |
71 /// | |
72 /// ``` | |
73 /// // build.rs | |
74 /// use libpam_sys::pam_impl; | |
75 /// fn main() { | |
76 /// println!("{}", pam_impl::enable_pam_impl_cfg()) | |
77 /// | |
78 /// // Whatever other stuff you do in your build.rs. | |
79 /// } | |
80 /// ``` | |
81 /// | |
82 /// This will set the current `pam_impl` as well as registering all known | |
83 /// PAM implementations with `rustc-check-cfg` so you can easily use them: | |
84 /// | |
85 /// ``` | |
86 /// #[cfg(pam_impl = "OpenPam")] | |
87 /// fn openpam_specific_func(handle: *const libpam_sys::pam_handle) { | |
88 /// let environ = libpam_sys::pam_getenvlist(handle); | |
89 /// // ... | |
90 /// libpam_sys::openpam_free_envlist() | |
91 /// } | |
92 /// | |
93 /// // This will give you a warning since "UnknownImpl" is not in the cfg. | |
94 /// #[cfg(not(pam_impl = "UnknownImpl"))] | |
95 /// fn do_something() { | |
96 /// // ... | |
97 /// } | |
98 /// ``` | |
99 #[cfg(pam_impl)] | |
100 pub fn enable_pam_impl_cfg() -> String { | |
101 format!("{}\n{}", checkcfg(), implcfg(PamImpl::CURRENT_STR)) | |
102 } | |
103 | |
104 /// Generates the `cargo:rustc-check-cfg` directive to print in build scripts. | |
105 fn checkcfg() -> String { | |
106 let impls: Vec<_> = PamImpl::items() | |
107 .into_iter() | |
108 .map(|i| format!(r#""{i:?}""#)) | |
109 .collect(); | |
110 format!( | |
111 "\ | |
112 cargo:rustc-check-cfg=cfg(pam_impl)\n\ | |
113 cargo:rustc-check-cfg=cfg(pam_impl, values({impls}))\ | |
114 ", | |
115 impls = impls.join(",") | |
116 ) | |
117 } | |
118 | |
119 fn implcfg(name: &str) -> String { | |
120 format!("cargo:rustc-cfg=pam_impl\ncargo:rustc-cfg=pam_impl={name:?}") | |
121 } |