1use serde::{Deserialize, Serialize};
9use std::{
10 cmp::Ordering,
11 collections::{BTreeMap, BTreeSet},
12};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
15#[serde(rename_all = "camelCase")]
16pub enum CascadeLevel {
17 UserAgentNormal,
18 UserNormal,
19 AuthorNormal,
20 InlineNormal,
21 Animation,
22 AuthorImportant,
23 UserImportant,
24 UserAgentImportant,
25 Transition,
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
29#[serde(rename_all = "camelCase")]
30pub struct LayerRank(pub i32);
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
33#[serde(rename_all = "camelCase")]
34pub struct Specificity {
35 pub ids: u32,
36 pub classes: u32,
37 pub elements: u32,
38}
39
40impl Specificity {
41 pub const ZERO: Self = Self {
42 ids: 0,
43 classes: 0,
44 elements: 0,
45 };
46
47 pub const fn new(ids: u32, classes: u32, elements: u32) -> Self {
48 Self {
49 ids,
50 classes,
51 elements,
52 }
53 }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
57#[serde(rename_all = "camelCase")]
58pub enum SpecificityExactnessV0 {
60 Exact,
62 Inexact,
64}
65
66impl Ord for Specificity {
67 fn cmp(&self, other: &Self) -> Ordering {
68 (self.ids, self.classes, self.elements).cmp(&(other.ids, other.classes, other.elements))
69 }
70}
71
72impl PartialOrd for Specificity {
73 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
74 Some(self.cmp(other))
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
79#[serde(rename_all = "camelCase")]
80pub struct ModuleRank {
81 pub distance_priority: u32,
82 pub import_order_priority: u32,
83 pub file_order_priority: u32,
84}
85
86impl ModuleRank {
87 pub const ZERO: Self = Self {
88 distance_priority: 0,
89 import_order_priority: 0,
90 file_order_priority: 0,
91 };
92
93 pub const fn new(
94 distance_priority: u32,
95 import_order_priority: u32,
96 file_order_priority: u32,
97 ) -> Self {
98 Self {
99 distance_priority,
100 import_order_priority,
101 file_order_priority,
102 }
103 }
104}
105
106impl Ord for ModuleRank {
107 fn cmp(&self, other: &Self) -> Ordering {
108 (
109 self.distance_priority,
110 self.import_order_priority,
111 self.file_order_priority,
112 )
113 .cmp(&(
114 other.distance_priority,
115 other.import_order_priority,
116 other.file_order_priority,
117 ))
118 }
119}
120
121impl PartialOrd for ModuleRank {
122 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
123 Some(self.cmp(other))
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
128#[serde(rename_all = "camelCase")]
129pub struct CascadeKey {
130 pub level: CascadeLevel,
131 pub layer_rank: LayerRank,
132 pub scope_proximity: u32,
133 pub specificity: Specificity,
134 pub module_rank: ModuleRank,
135 pub source_order: u32,
136}
137
138impl CascadeKey {
139 pub const fn new(
140 level: CascadeLevel,
141 layer_rank: LayerRank,
142 scope_proximity: u32,
143 specificity: Specificity,
144 module_rank: ModuleRank,
145 source_order: u32,
146 ) -> Self {
147 Self {
148 level,
149 layer_rank,
150 scope_proximity,
151 specificity,
152 module_rank,
153 source_order,
154 }
155 }
156}
157
158impl Ord for CascadeKey {
159 fn cmp(&self, other: &Self) -> Ordering {
160 self.level
161 .cmp(&other.level)
162 .then_with(|| self.layer_rank.cmp(&other.layer_rank))
163 .then_with(|| other.scope_proximity.cmp(&self.scope_proximity))
164 .then_with(|| self.specificity.cmp(&other.specificity))
165 .then_with(|| self.source_order.cmp(&other.source_order))
166 }
167}
168
169impl PartialOrd for CascadeKey {
170 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
171 Some(self.cmp(other))
172 }
173}
174
175#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
176#[serde(rename_all = "camelCase")]
177pub struct CascadeDeclaration {
178 pub id: String,
179 pub property: String,
180 pub value: CascadeValue,
181 pub key: CascadeKey,
182 pub specificity_exactness: SpecificityExactnessV0,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
187#[serde(rename_all = "camelCase")]
188pub struct CascadeProof {
189 pub declaration_id: String,
190 pub property: String,
191 pub level: CascadeLevel,
192 pub layer_rank: LayerRank,
193 pub scope_proximity: u32,
194 pub specificity: Specificity,
195 pub module_rank: ModuleRank,
196 pub source_order: u32,
197}
198
199impl CascadeProof {
200 pub fn from_declaration(declaration: &CascadeDeclaration) -> Self {
201 assert_eq!(
202 declaration.specificity_exactness,
203 SpecificityExactnessV0::Exact,
204 "cascade proofs require exact specificity"
205 );
206 Self {
207 declaration_id: declaration.id.clone(),
208 property: declaration.property.clone(),
209 level: declaration.key.level,
210 layer_rank: declaration.key.layer_rank,
211 scope_proximity: declaration.key.scope_proximity,
212 specificity: declaration.key.specificity,
213 module_rank: declaration.key.module_rank,
214 source_order: declaration.key.source_order,
215 }
216 }
217}
218
219#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
220#[serde(rename_all = "camelCase")]
221pub enum CascadeOutcome {
222 Definite {
223 winner: CascadeDeclaration,
224 proof: Box<CascadeProof>,
225 also_considered: Vec<CascadeDeclaration>,
226 },
227 RankedSet(Vec<CascadeDeclaration>),
228 Inherit,
229 Top,
230}
231
232#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
233#[serde(rename_all = "camelCase")]
234pub enum CascadeValue {
235 Literal(String),
236 Composite(Vec<CascadeValue>),
237 Var {
238 name: String,
239 fallback: Option<Box<CascadeValue>>,
240 },
241 Initial,
242 Inherit,
243 Indeterminate,
244 GuaranteedInvalid,
245 Unset,
246}
247
248#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
249#[serde(rename_all = "camelCase")]
250pub enum ComputedCascadeValueStatusV0 {
251 Resolved,
252 Inherited,
253 Initial,
254 Indeterminate,
255 InvalidAtComputedValueTime,
256}
257
258macro_rules! define_computed_cascade_indeterminate_reasons {
259 ($($variant:ident => $wire_name:literal),+ $(,)?) => {
260 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
261 #[serde(rename_all = "camelCase")]
262 pub enum ComputedCascadeIndeterminateReasonV0 {
263 $($variant),+
264 }
265
266 impl ComputedCascadeIndeterminateReasonV0 {
267 #[cfg(test)]
268 pub(crate) const ALL: &'static [Self] = &[$(Self::$variant),+];
269
270 pub const fn wire_name(self) -> &'static str {
271 match self {
272 $(Self::$variant => $wire_name),+
273 }
274 }
275 }
276 };
277}
278
279define_computed_cascade_indeterminate_reasons! {
280 CascadeOutcomeIndeterminate => "cascadeOutcomeIndeterminate",
281 PropertyInheritanceMetadataUnavailable => "propertyInheritanceMetadataUnavailable",
282 PropertyInitialValueMetadataUnavailable => "propertyInitialValueMetadataUnavailable",
283 RegisteredPropertySyntaxIndeterminate => "registeredPropertySyntaxIndeterminate",
284 InheritedFromIndeterminateParent => "inheritedFromIndeterminateParent",
285}
286
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
288#[serde(rename_all = "camelCase")]
289pub enum CascadeRegisteredValueVerdictV0 {
290 Matched,
291 Unmatched,
292 Unknown,
293}
294
295#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
296#[serde(rename_all = "camelCase")]
297pub struct CascadeRegisteredCustomPropertyV0 {
298 pub name: String,
299 pub inherits: bool,
300 pub initial_value: CascadeValue,
301 pub declaration_value_verdicts: BTreeMap<String, CascadeRegisteredValueVerdictV0>,
302}
303
304#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
305#[serde(rename_all = "camelCase")]
306pub struct CascadeComputedValueInputV0 {
307 pub property: String,
308 pub declarations: Vec<CascadeDeclaration>,
309 pub custom_property_env: CustomPropertyEnv,
310 pub parent_computed_value: Option<CascadeValue>,
311 #[serde(skip_serializing_if = "Option::is_none")]
312 pub registered_custom_property: Option<CascadeRegisteredCustomPropertyV0>,
313}
314
315#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
316#[serde(rename_all = "camelCase")]
317pub struct CascadeComputedValueResultV0 {
318 pub schema_version: &'static str,
319 pub product: &'static str,
320 pub property: String,
321 pub status: ComputedCascadeValueStatusV0,
322 pub value: CascadeValue,
323 pub winner_declaration_id: Option<String>,
324 pub inherited: bool,
325 pub used_initial_value: bool,
326 pub invalid_at_computed_value_time: bool,
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub indeterminate_reason: Option<ComputedCascadeIndeterminateReasonV0>,
329 pub derivation_steps: Vec<&'static str>,
330}
331
332#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
333#[serde(rename_all = "camelCase")]
334pub enum SelectorContextMatchKind {
335 NoMatch,
336 Global,
337 Root,
338 Exact,
339 ContainsSelector,
340 ApproximateSelector,
341}
342
343#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
344#[serde(rename_all = "camelCase")]
345pub struct SelectorContextWitness {
346 pub kind: SelectorContextMatchKind,
347 pub verdict: SelectorMatchVerdict,
348 pub matched: bool,
349 pub rank: usize,
350 pub declaration_selector: Option<String>,
351 pub reference_selector: Option<String>,
352}
353
354impl SelectorContextWitness {
355 pub fn no_match() -> Self {
356 Self {
357 kind: SelectorContextMatchKind::NoMatch,
358 verdict: SelectorMatchVerdict::No,
359 matched: false,
360 rank: 0,
361 declaration_selector: None,
362 reference_selector: None,
363 }
364 }
365}
366
367#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
368#[serde(rename_all = "camelCase")]
369pub struct ElementSignature {
370 pub tag: Option<String>,
371 pub id: Option<String>,
372 pub classes: BTreeSet<String>,
373 pub attributes: BTreeSet<String>,
374 pub pseudo_states: BTreeSet<String>,
375 pub classes_are_exact: bool,
376 pub attributes_are_exact: bool,
377 pub pseudo_states_are_exact: bool,
378 pub tag_is_exact: bool,
379 pub id_is_exact: bool,
380}
381
382#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
383#[serde(rename_all = "camelCase")]
384pub struct ElementIdentityV0 {
385 pub source_path: String,
386 pub byte_start: usize,
387 pub byte_end: usize,
388}
389
390#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
391#[serde(rename_all = "camelCase")]
392pub struct ElementSignatureWithParentsV0 {
393 pub identity: ElementIdentityV0,
394 pub signature: ElementSignature,
395 pub parent_chain: Vec<ElementIdentityV0>,
396 pub parent_chain_complete: bool,
397}
398
399#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
400#[serde(rename_all = "camelCase")]
401pub enum ElementParentChainStatusV0 {
402 Complete,
403 MissingSource,
404 MissingElement,
405 AmbiguousParent,
406 Cycle,
407}
408
409#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
410#[serde(rename_all = "camelCase")]
411pub struct ElementParentChainV0 {
412 pub target: ElementIdentityV0,
413 pub ancestors: Vec<ElementIdentityV0>,
414 pub status: ElementParentChainStatusV0,
415}
416
417#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
418#[serde(rename_all = "camelCase")]
419pub enum ScopeProximityStatusV0 {
420 Known,
421 IncompleteParentChain,
422 MissingElementSignature,
423 UnsupportedRootSelector,
424 NoMatchingRoot,
425}
426
427#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
428#[serde(rename_all = "camelCase")]
429pub struct ScopeProximityV0 {
430 pub status: ScopeProximityStatusV0,
431 pub distance: Option<u32>,
432 pub matched_root: Option<ElementIdentityV0>,
433 pub examined_element_count: usize,
434}
435
436impl ScopeProximityV0 {
437 pub const fn unknown(status: ScopeProximityStatusV0) -> Self {
438 Self {
439 status,
440 distance: None,
441 matched_root: None,
442 examined_element_count: 0,
443 }
444 }
445}
446
447impl ElementParentChainV0 {
448 pub fn is_complete(&self) -> bool {
449 self.status == ElementParentChainStatusV0::Complete
450 }
451}
452
453impl ElementSignature {
454 pub fn concrete(
455 tag: Option<impl Into<String>>,
456 id: Option<impl Into<String>>,
457 classes: impl IntoIterator<Item = impl Into<String>>,
458 ) -> Self {
459 Self {
460 tag: tag.map(Into::into),
461 id: id.map(Into::into),
462 classes: classes.into_iter().map(Into::into).collect(),
463 attributes: BTreeSet::new(),
464 pseudo_states: BTreeSet::new(),
465 classes_are_exact: true,
466 attributes_are_exact: true,
467 pseudo_states_are_exact: true,
468 tag_is_exact: true,
469 id_is_exact: true,
470 }
471 }
472
473 pub fn at_least_classes(classes: impl IntoIterator<Item = impl Into<String>>) -> Self {
474 Self {
475 classes_are_exact: false,
476 ..Self::concrete(None::<String>, None::<String>, classes)
477 }
478 }
479}
480
481#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
482#[serde(rename_all = "camelCase")]
483pub struct SelectorSignature {
484 pub selector: String,
485 pub required_tag: Option<String>,
486 pub required_id: Option<String>,
487 pub required_classes: BTreeSet<String>,
488 pub required_attributes: BTreeSet<String>,
489 pub required_pseudo_states: BTreeSet<String>,
490 pub specificity: Specificity,
491 pub specificity_exactness: SpecificityExactnessV0,
492}
493
494#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
495#[serde(rename_all = "camelCase")]
496pub enum SelectorMatchVerdict {
497 No,
498 Maybe,
499 Yes,
500}
501
502#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
503#[serde(rename_all = "camelCase")]
504pub enum SelectorMatchReason {
505 Universal,
506 SimpleCompound,
507 SelectorList,
508 MissingTag,
509 MissingId,
510 MissingClass,
511 MissingAttribute,
512 MissingPseudoState,
513 UnsupportedSelector,
514}
515
516#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
517#[serde(rename_all = "camelCase")]
518pub struct SelectorMatchWitness {
519 pub selector: String,
520 pub matched_branch: Option<String>,
521 pub verdict: SelectorMatchVerdict,
522 pub reason: SelectorMatchReason,
523 pub specificity: Specificity,
524 pub missing_tag: Option<String>,
525 pub missing_id: Option<String>,
526 pub missing_classes: BTreeSet<String>,
527 pub missing_attributes: BTreeSet<String>,
528 pub missing_pseudo_states: BTreeSet<String>,
529 pub unsupported_branches: Vec<String>,
530}
531
532impl SelectorMatchWitness {
533 pub(crate) fn unsupported(selector: &str) -> Self {
534 Self {
535 selector: selector.to_string(),
536 matched_branch: Some(selector.to_string()),
537 verdict: SelectorMatchVerdict::Maybe,
538 reason: SelectorMatchReason::UnsupportedSelector,
539 specificity: Specificity::ZERO,
540 missing_tag: None,
541 missing_id: None,
542 missing_classes: BTreeSet::new(),
543 missing_attributes: BTreeSet::new(),
544 missing_pseudo_states: BTreeSet::new(),
545 unsupported_branches: vec![selector.to_string()],
546 }
547 }
548}
549
550#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
551#[serde(rename_all = "camelCase")]
552pub struct CascadeBoundarySummary {
553 pub product: &'static str,
554 pub ordering_model: &'static str,
555 pub substitution_model: &'static str,
556 pub least_fixed_point_proof_model: &'static str,
557 pub ready_surfaces: Vec<&'static str>,
558 pub not_ready_surfaces: Vec<&'static str>,
559}
560
561#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
562#[serde(rename_all = "camelCase")]
563pub struct CascadeConformanceSeedCase {
564 pub name: String,
565 pub property: &'static str,
566 pub declarations: Vec<CascadeDeclaration>,
567 pub expected_outcome: &'static str,
568 pub expected_winner_id: Option<String>,
569}
570
571#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
572#[serde(rename_all = "camelCase")]
573pub struct CascadeConformanceSeedResult {
574 pub name: String,
575 pub passed: bool,
576 pub expected_outcome: &'static str,
577 pub actual_outcome: &'static str,
578 pub expected_winner_id: Option<String>,
579 pub actual_winner_id: Option<String>,
580}
581
582#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
583#[serde(rename_all = "camelCase")]
584pub struct CascadeConformanceSeedReport {
585 pub schema_version: &'static str,
586 pub product: &'static str,
587 pub case_count: usize,
588 pub passed_count: usize,
589 pub failed_count: usize,
590 pub results: Vec<CascadeConformanceSeedResult>,
591}
592
593#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
594#[serde(rename_all = "camelCase")]
595pub struct CascadeEvaluationFuzzCaseV0 {
596 pub seed: u64,
597 pub declaration_count: usize,
598}
599
600#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
601#[serde(rename_all = "camelCase")]
602pub struct CascadeEvaluationFuzzResultV0 {
603 pub seed: u64,
604 pub declaration_count: usize,
605 pub actual_winner_id: Option<String>,
606 pub expected_winner_id: Option<String>,
607 pub ranked_count: usize,
608 pub passed: bool,
609}
610
611#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
612#[serde(rename_all = "camelCase")]
613pub struct VarSubstitutionFuzzCaseV0 {
614 pub seed: u64,
615 pub chain_len: usize,
616 pub cycle: bool,
617}
618
619#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
620#[serde(rename_all = "camelCase")]
621pub struct VarSubstitutionFuzzResultV0 {
622 pub seed: u64,
623 pub chain_len: usize,
624 pub cycle: bool,
625 pub result: CascadeValue,
626 pub expected: CascadeValue,
627 pub passed: bool,
628}
629
630#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
631#[serde(rename_all = "camelCase")]
632pub struct CustomPropertyLeastFixedPointSummaryV0 {
633 pub schema_version: &'static str,
634 pub product: &'static str,
635 pub input_count: usize,
636 pub resolved_count: usize,
637 pub guaranteed_invalid_count: usize,
638 pub iteration_count: usize,
639 pub iteration_bound: usize,
640 pub reached_fixed_point: bool,
641 pub monotone_witness_valid: bool,
642 pub proof: CustomPropertyLeastFixedPointProofV0,
643 pub iteration_trace: Vec<CustomPropertyLeastFixedPointIterationV0>,
644 pub entries: Vec<CustomPropertyLeastFixedPointEntryV0>,
645 pub ready_surfaces: Vec<&'static str>,
646}
647
648#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
649#[serde(rename_all = "camelCase")]
650pub struct CustomPropertyLeastFixedPointProofV0 {
651 pub finite_domain: &'static str,
652 pub transfer_function: &'static str,
653 pub monotone_witness: &'static str,
654 pub iteration_bound_formula: &'static str,
655 pub cycle_policy: &'static str,
656 pub proof_obligations: Vec<&'static str>,
657}
658
659#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
660#[serde(rename_all = "camelCase")]
661pub struct CustomPropertyLeastFixedPointIterationV0 {
662 pub iteration: usize,
663 pub changed_count: usize,
664 pub settled_count: usize,
665 pub guaranteed_invalid_count: usize,
666}
667
668#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
669#[serde(rename_all = "camelCase")]
670pub struct CustomPropertyLeastFixedPointEntryV0 {
671 pub name: String,
672 pub input: CascadeValue,
673 pub resolved: CascadeValue,
674 pub changed: bool,
675 pub guaranteed_invalid: bool,
676}
677
678#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
679#[serde(rename_all = "camelCase")]
680pub struct CascadeFuzzSeedReportV0 {
681 pub schema_version: &'static str,
682 pub product: &'static str,
683 pub case_count: usize,
684 pub passed_count: usize,
685 pub failed_count: usize,
686 pub cascade_results: Vec<CascadeEvaluationFuzzResultV0>,
687 pub var_results: Vec<VarSubstitutionFuzzResultV0>,
688}
689
690#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
691#[serde(rename_all = "camelCase")]
692pub struct BoxLonghandInputV0 {
693 pub property: String,
694 pub value: String,
695 pub important: bool,
696 pub source_order: u32,
697}
698
699pub type LonghandMergeInputV0 = BoxLonghandInputV0;
700
701#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
702#[serde(rename_all = "camelCase")]
703pub struct ShorthandCombinationProofV0 {
704 pub schema_version: &'static str,
705 pub product: &'static str,
706 pub shorthand_property: String,
707 pub accepted: bool,
708 pub blocked_reason: Option<&'static str>,
709 pub ordered_longhand_properties: Vec<String>,
710 pub provenance_preserved: bool,
711 pub cascade_safe_witness: String,
712}
713
714pub type LonghandMergeProofV0 = ShorthandCombinationProofV0;
715
716#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
717#[serde(default, rename_all = "camelCase")]
718pub struct SupportsTargetCapabilityV0 {
719 pub supports_light_dark: bool,
720 pub supports_color_mix: bool,
721 pub supports_oklch_oklab: bool,
722 pub supports_color_function: bool,
723 pub supports_relative_color: bool,
724 pub supports_logical_properties: bool,
725 pub supports_css_nesting: bool,
726 pub supports_css_scope: bool,
727 pub supports_cascade_layers: bool,
728}
729
730impl SupportsTargetCapabilityV0 {
731 pub const fn all_supported() -> Self {
732 Self {
733 supports_light_dark: true,
734 supports_color_mix: true,
735 supports_oklch_oklab: true,
736 supports_color_function: true,
737 supports_relative_color: true,
738 supports_logical_properties: true,
739 supports_css_nesting: true,
740 supports_css_scope: true,
741 supports_cascade_layers: true,
742 }
743 }
744
745 pub const fn none_supported() -> Self {
746 Self {
747 supports_light_dark: false,
748 supports_color_mix: false,
749 supports_oklch_oklab: false,
750 supports_color_function: false,
751 supports_relative_color: false,
752 supports_logical_properties: false,
753 supports_css_nesting: false,
754 supports_css_scope: false,
755 supports_cascade_layers: false,
756 }
757 }
758}
759
760impl Default for SupportsTargetCapabilityV0 {
761 fn default() -> Self {
762 Self::none_supported()
763 }
764}
765
766#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
767#[serde(rename_all = "camelCase")]
768pub enum StaticSupportsAssumptionV0 {
769 ModernBrowser,
770 TargetCapability(SupportsTargetCapabilityV0),
771}
772
773#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
774#[serde(rename_all = "camelCase")]
775pub enum StaticSupportsEvalVerdictV0 {
776 AlwaysTrue,
777 AlwaysFalse,
778 Unknown,
779}
780
781#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
782#[serde(rename_all = "camelCase")]
783pub struct StaticSupportsEvalWitnessV0 {
784 pub schema_version: &'static str,
785 pub product: &'static str,
786 pub condition: String,
787 pub assumption: StaticSupportsAssumptionV0,
788 pub verdict: StaticSupportsEvalVerdictV0,
789 pub reason: &'static str,
790 pub provenance_preserved: bool,
791}
792
793#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
794#[serde(rename_all = "camelCase")]
795pub struct ScopeFlattenInputV0 {
796 pub root_selector: String,
797 pub limit_selector: Option<String>,
798 pub scoped_rule_count: usize,
799 pub peer_scope_count: usize,
800 pub competing_unscoped_rule_count: usize,
801 pub inside_layer: bool,
802}
803
804#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
805#[serde(rename_all = "camelCase")]
806pub struct ScopeFlattenProofV0 {
807 pub schema_version: &'static str,
808 pub product: &'static str,
809 pub accepted: bool,
810 pub blocked_reason: Option<&'static str>,
811 pub root_selector: String,
812 pub provenance_preserved: bool,
813 pub cascade_safe_witness: String,
814}
815
816#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
817#[serde(rename_all = "camelCase")]
818pub struct LayerFlattenInputV0 {
819 pub layer_name: Option<String>,
820 pub layer_rule_count: usize,
821 pub peer_layer_count: usize,
822 pub unlayered_rule_count: usize,
823 pub important_declaration_count: usize,
824 pub closed_bundle: bool,
825}
826
827#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
828#[serde(rename_all = "camelCase")]
829pub struct LayerFlattenProofV0 {
830 pub schema_version: &'static str,
831 pub product: &'static str,
832 pub accepted: bool,
833 pub blocked_reason: Option<&'static str>,
834 pub layer_name: Option<String>,
835 pub provenance_preserved: bool,
836 pub cascade_safe_witness: String,
837}
838
839#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
840#[serde(tag = "witnessKind", content = "witness", rename_all = "camelCase")]
841pub enum ModalCheckWitnessSourceV0 {
842 ShorthandCombination(ShorthandCombinationProofV0),
843 StaticSupportsEval(StaticSupportsEvalWitnessV0),
844 ScopeFlatten(ScopeFlattenProofV0),
845 LayerFlatten(LayerFlattenProofV0),
846}
847
848#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
849#[serde(rename_all = "camelCase")]
850pub struct ModalCheckWitnessV0 {
855 pub schema_version: &'static str,
856 pub product: &'static str,
857 pub modal_family: &'static str,
858 pub substrate: &'static str,
859 pub obligation_count: usize,
860 pub accepted_count: usize,
861 pub blocked_count: usize,
862 pub all_provenance_preserved: bool,
863 pub source_products: Vec<&'static str>,
864 pub witnesses: Vec<ModalCheckWitnessSourceV0>,
865}
866
867#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
868#[serde(rename_all = "camelCase")]
869pub struct CascadeMarginSchemaV0 {
870 pub schema_version: &'static str,
871 pub product: &'static str,
872 pub margin_kind: &'static str,
873 pub axis_order: Vec<&'static str>,
874 pub calibration_stage: &'static str,
875 pub public_safety_claim_ready: bool,
876}
877
878#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
879#[serde(rename_all = "camelCase")]
880pub struct CascadeMarginV0 {
881 pub schema_version: &'static str,
882 pub product: &'static str,
883 pub margin_kind: &'static str,
884 pub winner_declaration_id: String,
885 pub challenger_declaration_id: Option<String>,
886 pub dominant_axis: &'static str,
887 pub signed_distance: i64,
888 pub winner_key: CascadeKey,
889 pub challenger_key: Option<CascadeKey>,
890 pub calibration_stage: &'static str,
891 pub public_safety_claim_ready: bool,
892}
893
894pub type CustomPropertyEnv = BTreeMap<String, CascadeValue>;