Skip to main content

isoloom_plan/requirements/
feature.rs

1//! Every [`Feature`], and each one's name: what the capability matrix (`isoloom matrix`) lists and
2//! names a refusal by. Both come from one list, so a feature added to the enum fails to build
3//! here until it is named: [`Feature::id`]'s `match` covers every one, and [`Feature::ALL`] is
4//! the same list.
5
6use super::Feature;
7
8/// [`Feature::ALL`] and [`Feature::id`] from one list of `variant => "name"`.
9macro_rules! named {
10    ($($feature:ident => $id:literal,)*) => {
11        impl Feature {
12            /// Every feature, in the order the enum declares them.
13            pub const ALL: &'static [Feature] = &[$(Feature::$feature),*];
14
15            /// Its name, in kebab case (`ipv6-only`, `vm-gpus`).
16            #[must_use]
17            pub fn id(self) -> &'static str {
18                match self {
19                    $(Feature::$feature => $id,)*
20                }
21            }
22        }
23    };
24}
25
26named! {
27    EnvironmentProvisioning => "environment-provisioning",
28    PlaybookChecks => "playbook-checks",
29    ExecWithoutContainer => "exec-without-container",
30    NetworkAppliances => "network-appliances",
31    Gateways => "gateways",
32    VolumesAcrossShapes => "volumes-across-shapes",
33    VmAfterContainer => "vm-after-container",
34    MachineAliases => "machine-aliases",
35    Ulimits => "ulimits",
36    TrafficControl => "traffic-control",
37    Ipv6 => "ipv6",
38    Ipv6Only => "ipv6-only",
39    Ipv6Auto => "ipv6-auto",
40    Secrets => "secrets",
41    SecretOwners => "secret-owners",
42    ExternalNetworks => "external-networks",
43    BridgedNetworks => "bridged-networks",
44    OwnedProjectFiles => "owned-project-files",
45    ExistingHostFiles => "existing-host-files",
46    Tpm => "tpm",
47    MachineProcess => "machine-process",
48    OwnBoot => "own-boot",
49    ContainerGpus => "container-gpus",
50    ContainerDevices => "container-devices",
51    ContainerNestedVirtualization => "container-nested-virtualization",
52    VmGpus => "vm-gpus",
53    VmDevices => "vm-devices",
54    NestedVirtualization => "nested-virtualization",
55    NetworkMtu => "network-mtu",
56    RateLimit => "rate-limit",
57    PrivateDns => "private-dns",
58    PersistentVolumes => "persistent-volumes",
59    ExternalVolumes => "external-volumes",
60    DataDisks => "data-disks",
61    RawDisks => "raw-disks",
62    TmpfsModes => "tmpfs-modes",
63    VmMoreAddresses => "vm-more-addresses",
64    ContainerMoreAddresses => "container-more-addresses",
65}
66
67#[cfg(test)]
68mod tests {
69    use std::collections::BTreeSet;
70
71    use super::*;
72
73    #[test]
74    fn every_feature_has_its_own_kebab_case_name_and_is_listed_in_order() {
75        let names: BTreeSet<&str> = Feature::ALL.iter().map(|f| f.id()).collect();
76        assert_eq!(names.len(), Feature::ALL.len());
77        assert!(
78            names
79                .iter()
80                .all(|n| n.bytes().all(|b| b.is_ascii_lowercase() || b.is_ascii_digit() || b == b'-'))
81        );
82        assert!(Feature::ALL.is_sorted(), "in the order the enum declares them");
83    }
84}