Skip to main content

pedant_types/
capability.rs

1use std::fmt;
2use std::str::FromStr;
3
4use serde::{Deserialize, Serialize};
5
6use crate::ParseCapabilityError;
7
8/// Define a Capability variant ↔ snake_case string mapping in one place.
9///
10/// Generates `Display` and `FromStr` from the same table so the two
11/// cannot drift. Serde uses `rename_all = "snake_case"` independently
12/// but produces identical strings for the same variants.
13macro_rules! capability_variants {
14    ($($(#[$meta:meta])* $variant:ident => $snake:literal),+ $(,)?) => {
15        /// A runtime or compile-time capability that a crate may exercise.
16        #[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
17        #[serde(rename_all = "snake_case")]
18        pub enum Capability {
19            $($(#[$meta])* $variant,)+
20        }
21
22        impl fmt::Display for Capability {
23            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24                let s = match self {
25                    $(Self::$variant => $snake,)+
26                };
27                f.write_str(s)
28            }
29        }
30
31        impl FromStr for Capability {
32            type Err = ParseCapabilityError;
33
34            fn from_str(s: &str) -> Result<Self, Self::Err> {
35                match s {
36                    $($snake => Ok(Self::$variant),)+
37                    _ => Err(ParseCapabilityError::new(s)),
38                }
39            }
40        }
41    };
42}
43
44capability_variants! {
45    /// TCP, UDP, HTTP, WebSocket, or DNS.
46    Network => "network",
47    /// Reading files or walking directories.
48    FileRead => "file_read",
49    /// Creating, writing, or deleting files and directories.
50    FileWrite => "file_write",
51    /// Spawning child processes.
52    ProcessExec => "process_exec",
53    /// Reading environment variables.
54    EnvAccess => "env_access",
55    /// `unsafe` blocks, `unsafe fn`, or `unsafe impl`.
56    UnsafeCode => "unsafe_code",
57    /// Foreign function interface calls or `extern` blocks.
58    Ffi => "ffi",
59    /// Encryption, hashing, signing, or embedded key material.
60    Crypto => "crypto",
61    /// `SystemTime`, `Instant`, or third-party clock access.
62    SystemTime => "system_time",
63    /// Proc macro definition (code execution at compile time).
64    ProcMacro => "proc_macro",
65}