1use super::Backend;
4
5#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
7#[non_exhaustive]
8pub enum OperationKind {
9 Encode,
11 StrictDecode,
13 SecretDecode,
15}
16
17impl OperationKind {
18 #[must_use]
20 pub const fn as_str(self) -> &'static str {
21 match self {
22 Self::Encode => "encode",
23 Self::StrictDecode => "strict-decode",
24 Self::SecretDecode => "secret-decode",
25 }
26 }
27}
28
29#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
34pub struct BackendIdentifier(&'static str);
35
36impl BackendIdentifier {
37 pub(crate) const SCALAR_CT_ORIENTED: Self = Self("scalar-constant-time-oriented");
38
39 pub(crate) const fn ordinary(backend: Backend) -> Self {
40 Self(backend.as_str())
41 }
42
43 #[must_use]
45 pub const fn as_str(self) -> &'static str {
46 self.0
47 }
48}
49
50impl core::fmt::Display for BackendIdentifier {
51 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
52 formatter.write_str(self.0)
53 }
54}
55
56#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
58#[non_exhaustive]
59pub enum OperationSecurityPosture {
60 OrdinaryScalar,
62 OrdinaryAccelerated,
64 ScalarConstantTimeOriented,
66}
67
68impl OperationSecurityPosture {
69 #[must_use]
71 pub const fn as_str(self) -> &'static str {
72 match self {
73 Self::OrdinaryScalar => "ordinary-scalar",
74 Self::OrdinaryAccelerated => "ordinary-accelerated",
75 Self::ScalarConstantTimeOriented => "scalar-constant-time-oriented",
76 }
77 }
78}
79
80#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
82#[non_exhaustive]
83pub enum BackendHealthPosture {
84 ScalarFixed,
86 NeverRun,
88 Testing,
90 Healthy,
92 Quarantined,
94 SynchronizationUnavailable,
96 SecretPolicyFixed,
99}
100
101impl BackendHealthPosture {
102 #[must_use]
104 pub const fn as_str(self) -> &'static str {
105 match self {
106 Self::ScalarFixed => "scalar-fixed",
107 Self::NeverRun => "never-run",
108 Self::Testing => "testing",
109 Self::Healthy => "healthy",
110 Self::Quarantined => "quarantined",
111 Self::SynchronizationUnavailable => "synchronization-unavailable",
112 Self::SecretPolicyFixed => "secret-policy-fixed",
113 }
114 }
115}
116
117#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
119#[non_exhaustive]
120pub enum WasmArtifactPosture {
121 NotWasm,
123 ScalarArtifact,
125 Simd128Artifact,
127}
128
129impl WasmArtifactPosture {
130 #[must_use]
132 pub const fn as_str(self) -> &'static str {
133 match self {
134 Self::NotWasm => "not-wasm",
135 Self::ScalarArtifact => "wasm-scalar-artifact",
136 Self::Simd128Artifact => "wasm-simd128-artifact",
137 }
138 }
139}
140
141#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
143#[non_exhaustive]
144pub enum WasmRuntimePosture {
145 NotWasm,
147 HostRuntimeUnidentified,
149}
150
151impl WasmRuntimePosture {
152 #[must_use]
154 pub const fn as_str(self) -> &'static str {
155 match self {
156 Self::NotWasm => "not-wasm",
157 Self::HostRuntimeUnidentified => "wasm-host-runtime-unidentified",
158 }
159 }
160}
161
162#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
164pub struct OperationBackendReport {
165 pub operation: OperationKind,
167 pub backend: BackendIdentifier,
169 pub security_posture: OperationSecurityPosture,
171 pub health_posture: BackendHealthPosture,
173 pub health_generation: usize,
178 pub backend_fault: Option<crate::BackendFault>,
180}
181
182impl OperationBackendReport {
183 pub(crate) fn ordinary(operation: OperationKind, backend: Backend, candidate: Backend) -> Self {
184 let security_posture = if matches!(backend, Backend::Scalar) {
185 OperationSecurityPosture::OrdinaryScalar
186 } else {
187 OperationSecurityPosture::OrdinaryAccelerated
188 };
189 let health = crate::v2::backend_health::snapshot(operation, candidate);
190 let health_posture = if candidate == Backend::Scalar {
191 BackendHealthPosture::ScalarFixed
192 } else {
193 match health.state {
194 crate::BackendHealthState::NeverRun => {
195 if cfg!(target_has_atomic = "ptr") {
196 BackendHealthPosture::NeverRun
197 } else {
198 BackendHealthPosture::SynchronizationUnavailable
199 }
200 }
201 crate::BackendHealthState::Testing => BackendHealthPosture::Testing,
202 crate::BackendHealthState::Healthy => BackendHealthPosture::Healthy,
203 crate::BackendHealthState::Quarantined => BackendHealthPosture::Quarantined,
204 }
205 };
206 Self {
207 operation,
208 backend: BackendIdentifier::ordinary(backend),
209 security_posture,
210 health_posture,
211 health_generation: health.generation,
212 backend_fault: health.fault,
213 }
214 }
215
216 pub(crate) const fn secret_decode() -> Self {
217 Self {
218 operation: OperationKind::SecretDecode,
219 backend: BackendIdentifier::SCALAR_CT_ORIENTED,
220 security_posture: OperationSecurityPosture::ScalarConstantTimeOriented,
221 health_posture: BackendHealthPosture::SecretPolicyFixed,
222 health_generation: 1,
223 backend_fault: None,
224 }
225 }
226
227 #[must_use]
229 pub const fn snapshot(self) -> OperationBackendSnapshot {
230 OperationBackendSnapshot {
231 operation: self.operation.as_str(),
232 backend: self.backend.as_str(),
233 security_posture: self.security_posture.as_str(),
234 health_posture: self.health_posture.as_str(),
235 health_generation: self.health_generation,
236 backend_fault: match self.backend_fault {
237 Some(fault) => Some(fault.as_str()),
238 None => None,
239 },
240 }
241 }
242}
243
244#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
246pub struct OperationBackendSnapshot {
247 pub operation: &'static str,
249 pub backend: &'static str,
251 pub security_posture: &'static str,
253 pub health_posture: &'static str,
255 pub health_generation: usize,
257 pub backend_fault: Option<&'static str>,
259}
260
261pub(crate) const fn wasm_artifact_posture() -> WasmArtifactPosture {
262 #[cfg(all(feature = "simd", target_arch = "wasm32"))]
263 if crate::simd::wasm_simd128_artifact_selected() {
264 return WasmArtifactPosture::Simd128Artifact;
265 }
266 if cfg!(target_arch = "wasm32") {
267 WasmArtifactPosture::ScalarArtifact
268 } else {
269 WasmArtifactPosture::NotWasm
270 }
271}
272
273pub(crate) const fn wasm_runtime_posture() -> WasmRuntimePosture {
274 if cfg!(target_arch = "wasm32") {
275 WasmRuntimePosture::HostRuntimeUnidentified
276 } else {
277 WasmRuntimePosture::NotWasm
278 }
279}