Skip to main content

qubit_validator/report/
skipped_validation.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! Explicitly skipped validation occurrences.
10
11use super::FailureId;
12use super::SkipReason;
13use super::ValidationOutcomeError;
14use super::ValidationPath;
15
16/// One validation occurrence that was skipped by the executor.
17///
18/// # Examples
19///
20/// ```
21/// use qubit_validator::{SkipReason, SkippedValidation, ValidationPath};
22///
23/// let skipped = SkippedValidation::missing_optional(
24///     0,
25///     ValidationPath::root().with_field("optional"),
26/// );
27/// assert_eq!(skipped.reason(), SkipReason::MissingOptional);
28/// ```
29#[must_use]
30#[derive(Clone, Debug, Eq, PartialEq)]
31pub struct SkippedValidation {
32    /// Zero-based declaration occurrence assigned by the executor.
33    occurrence: usize,
34    /// Structured path of the skipped target.
35    path: ValidationPath,
36    /// Policy reason the occurrence did not execute.
37    reason: SkipReason,
38    /// IDs of failures that prevented this occurrence; empty for an absent
39    /// optional target.
40    prerequisites: Vec<FailureId>,
41}
42
43impl SkippedValidation {
44    /// Creates a record for an absent optional target.
45    ///
46    /// # Parameters
47    ///
48    /// - `occurrence`: Zero-based declaration position of the skipped target.
49    /// - `path`: Structured path identifying the absent target.
50    ///
51    /// # Returns
52    ///
53    /// A skipped occurrence with no prerequisite failures.
54    #[inline]
55    pub fn missing_optional(occurrence: usize, path: ValidationPath) -> Self {
56        Self {
57            occurrence,
58            path,
59            reason: SkipReason::MissingOptional,
60            prerequisites: Vec::new(),
61        }
62    }
63
64    /// Creates a record for an occurrence skipped after prerequisite
65    /// failures.
66    ///
67    /// # Parameters
68    ///
69    /// - `occurrence`: Zero-based declaration position of the skipped target.
70    /// - `path`: Structured path identifying the skipped target.
71    /// - `prerequisites`: Failure IDs that prevented this occurrence from
72    ///   running.
73    ///
74    /// # Errors
75    ///
76    /// Returns `EmptyPrerequisites` when no failure ID is supplied.
77    ///
78    /// # Returns
79    ///
80    /// A skipped occurrence containing the supplied prerequisite failure IDs.
81    pub fn failed_prerequisite(
82        occurrence: usize,
83        path: ValidationPath,
84        prerequisites: Vec<FailureId>,
85    ) -> Result<Self, ValidationOutcomeError> {
86        if prerequisites.is_empty() {
87            return Err(ValidationOutcomeError::EmptyPrerequisites);
88        }
89        Ok(Self {
90            occurrence,
91            path,
92            reason: SkipReason::FailedPrerequisite,
93            prerequisites,
94        })
95    }
96
97    /// Returns the zero-based declaration occurrence assigned by the executor.
98    ///
99    /// # Returns
100    ///
101    /// The occurrence number used to order this validation result.
102    #[must_use]
103    #[inline]
104    pub const fn occurrence(&self) -> usize {
105        self.occurrence
106    }
107
108    /// Returns the structured path of the skipped target.
109    ///
110    /// # Returns
111    ///
112    /// A borrow of the target path stored in this record.
113    #[must_use]
114    #[inline]
115    pub const fn path(&self) -> &ValidationPath {
116        &self.path
117    }
118
119    /// Returns why the executor did not run this occurrence.
120    ///
121    /// # Returns
122    ///
123    /// The policy reason that caused the skip.
124    #[must_use]
125    #[inline]
126    pub const fn reason(&self) -> SkipReason {
127        self.reason
128    }
129
130    /// Returns IDs of failures that prevented this occurrence.
131    ///
132    /// # Returns
133    ///
134    /// The prerequisite IDs, or an empty slice when an optional target was
135    /// absent.
136    #[must_use = "inspect the prerequisite failure IDs"]
137    #[inline]
138    pub fn prerequisites(&self) -> &[FailureId] {
139        &self.prerequisites
140    }
141}