Skip to main content

qubit_metadata/
metadata_validation_error.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! [`MetadataValidationError`] — aggregate schema validation failures.
11
12use std::fmt;
13
14use crate::metadata_error::MetadataError;
15
16/// Aggregate error returned by schema-level validation APIs.
17///
18/// Unlike single-entry metadata accessors, schema validation can discover
19/// multiple independent issues in one pass. This type preserves all collected
20/// [`MetadataError`] values so callers can report or fix them together.
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct MetadataValidationError {
23    /// Collected validation issues.
24    issues: Vec<MetadataError>,
25}
26
27impl MetadataValidationError {
28    /// Creates an aggregate validation error from one issue.
29    #[inline]
30    #[must_use]
31    pub fn from_issue(issue: MetadataError) -> Self {
32        Self { issues: vec![issue] }
33    }
34
35    /// Creates an aggregate validation error from a non-empty issue list.
36    ///
37    /// Returns `None` when `issues` is empty because an empty validation error
38    /// has no actionable meaning.
39    #[inline]
40    #[must_use]
41    pub fn from_issues(issues: Vec<MetadataError>) -> Option<Self> {
42        (!issues.is_empty()).then_some(Self { issues })
43    }
44
45    /// Returns the collected validation issues.
46    #[inline]
47    #[must_use]
48    pub fn issues(&self) -> &[MetadataError] {
49        &self.issues
50    }
51
52    /// Returns the number of collected validation issues.
53    #[inline]
54    #[must_use]
55    pub fn len(&self) -> usize {
56        self.issues.len()
57    }
58
59    /// Returns `true` when no issues are stored.
60    #[inline]
61    #[must_use]
62    pub fn is_empty(&self) -> bool {
63        self.issues.is_empty()
64    }
65
66    /// Converts this aggregate error into its collected issues.
67    #[inline]
68    #[must_use]
69    pub fn into_issues(self) -> Vec<MetadataError> {
70        self.issues
71    }
72}
73
74impl fmt::Display for MetadataValidationError {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        write!(f, "{} metadata validation issue(s)", self.issues.len())?;
77        for (index, issue) in self.issues.iter().enumerate() {
78            write!(f, "; {}: {issue}", index + 1)?;
79        }
80        Ok(())
81    }
82}
83
84impl std::error::Error for MetadataValidationError {}