Skip to main content

devscout_rs/truth/
profile.rs

1//! The compatibility-profile registry.
2//!
3//! Seven dimensions (host, project/build context, target API contract,
4//! language/compiler, application framework, platform/workload,
5//! execution context) combined into a named `Profile`. No profile
6//! registered here claims `Passing`/`Failing` -- those live only on the
7//! per-axis capability matrix, and only once an obligation has actually
8//! executed. This registry states the intended inventory and, for the
9//! handful of demonstrated targets, that they have been smoke-tested;
10//! earning a stronger state for a promised target is a later ticket's
11//! job, not this file's.
12
13use super::capability::CapabilityState;
14
15/// One of the seven registered compatibility dimensions.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17pub enum Dimension {
18    /// The analyzer host (SDK/tool version) a profile runs under.
19    Host,
20    /// The project/build-context model a profile assumes.
21    ProjectBuildContext,
22    /// The target API surface a profile is checked against.
23    TargetApiContract,
24    /// The language/compiler pairing a profile assumes.
25    LanguageCompiler,
26    /// The application framework a profile's cases target.
27    ApplicationFramework,
28    /// The platform/workload a profile targets.
29    PlatformWorkload,
30    /// The execution context (local, CI, scheduled) a profile runs under.
31    ExecutionContext,
32}
33
34impl Dimension {
35    /// Every registered dimension, in declaration order.
36    pub const ALL: [Dimension; 7] = [
37        Dimension::Host,
38        Dimension::ProjectBuildContext,
39        Dimension::TargetApiContract,
40        Dimension::LanguageCompiler,
41        Dimension::ApplicationFramework,
42        Dimension::PlatformWorkload,
43        Dimension::ExecutionContext,
44    ];
45
46    /// The wire label for this dimension.
47    pub fn label(self) -> &'static str {
48        match self {
49            Dimension::Host => "host",
50            Dimension::ProjectBuildContext => "project-build-context",
51            Dimension::TargetApiContract => "target-api-contract",
52            Dimension::LanguageCompiler => "language-compiler",
53            Dimension::ApplicationFramework => "application-framework",
54            Dimension::PlatformWorkload => "platform-workload",
55            Dimension::ExecutionContext => "execution-context",
56        }
57    }
58}
59
60/// A named combination of the seven dimensions, plus the ceiling this
61/// registry claims for it today. The ceiling is never `Passing`/`Failing`
62/// -- see the module note.
63#[derive(Debug, Clone)]
64pub struct Profile {
65    /// The profile's stable id.
66    pub id: &'static str,
67    /// The target framework moniker this profile names.
68    pub target_framework: &'static str,
69    /// The strongest capability state this registry claims for the profile.
70    pub ceiling: CapabilityState,
71}
72
73/// The full intended inventory: every entry `planned` or `unavailable`
74/// except the demonstrated targets, which claim at most `smoke-tested`
75/// under the pinned host this registry was probed against.
76pub const REGISTERED_PROFILES: &[Profile] = &[
77    Profile {
78        id: "csharp-net8.0-sdk",
79        target_framework: "net8.0",
80        ceiling: CapabilityState::SmokeTested,
81    },
82    Profile {
83        id: "csharp-netcoreapp3.1-sdk",
84        target_framework: "netcoreapp3.1",
85        ceiling: CapabilityState::SmokeTested,
86    },
87    Profile {
88        id: "csharp-net472-framework",
89        target_framework: "net472",
90        ceiling: CapabilityState::SmokeTested,
91    },
92    Profile {
93        id: "csharp-netstandard2.1-library",
94        target_framework: "netstandard2.1",
95        ceiling: CapabilityState::SmokeTested,
96    },
97    Profile {
98        id: "csharp-net40-framework",
99        target_framework: "net40",
100        ceiling: CapabilityState::Planned,
101    },
102    Profile {
103        id: "csharp-net481-framework",
104        target_framework: "net481",
105        ceiling: CapabilityState::Planned,
106    },
107    Profile {
108        id: "csharp-net10.0-sdk",
109        target_framework: "net10.0",
110        ceiling: CapabilityState::Planned,
111    },
112    Profile {
113        id: "csharp-netcoreapp2.x-sdk",
114        target_framework: "netcoreapp2.x",
115        ceiling: CapabilityState::Unavailable,
116    },
117    Profile {
118        id: "csharp-netstandard1.0-library",
119        target_framework: "netstandard1.0",
120        ceiling: CapabilityState::Planned,
121    },
122];
123
124/// Looks up a registered profile by id.
125pub fn find(id: &str) -> Option<&'static Profile> {
126    REGISTERED_PROFILES.iter().find(|p| p.id == id)
127}
128
129#[cfg(test)]
130mod tests {
131    use super::*;
132
133    #[test]
134    fn no_registered_profile_claims_passing_or_failing() {
135        for profile in REGISTERED_PROFILES {
136            assert!(
137                !matches!(
138                    profile.ceiling,
139                    CapabilityState::Passing(_) | CapabilityState::Failing
140                ),
141                "{} claims a state this registry may not assert",
142                profile.id
143            );
144        }
145    }
146
147    #[test]
148    fn the_four_demonstrated_targets_are_registered_at_most_smoke_tested() {
149        for id in [
150            "csharp-net8.0-sdk",
151            "csharp-netcoreapp3.1-sdk",
152            "csharp-net472-framework",
153            "csharp-netstandard2.1-library",
154        ] {
155            let profile = find(id).unwrap_or_else(|| panic!("{id} must be registered"));
156            assert_eq!(profile.ceiling, CapabilityState::SmokeTested);
157        }
158    }
159
160    #[test]
161    fn lookup_of_an_unregistered_id_is_none() {
162        assert!(find("csharp-vb-anything").is_none());
163    }
164}