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 {
33            issues: vec![issue],
34        }
35    }
36
37    /// Creates an aggregate validation error from a non-empty issue list.
38    ///
39    /// Returns `None` when `issues` is empty because an empty validation error
40    /// has no actionable meaning.
41    #[inline]
42    #[must_use]
43    pub fn from_issues(issues: Vec<MetadataError>) -> Option<Self> {
44        (!issues.is_empty()).then_some(Self { issues })
45    }
46
47    /// Returns the collected validation issues.
48    #[inline]
49    #[must_use]
50    pub fn issues(&self) -> &[MetadataError] {
51        &self.issues
52    }
53
54    /// Returns the number of collected validation issues.
55    #[inline]
56    #[must_use]
57    pub fn len(&self) -> usize {
58        self.issues.len()
59    }
60
61    /// Returns `true` when no issues are stored.
62    #[inline]
63    #[must_use]
64    pub fn is_empty(&self) -> bool {
65        self.issues.is_empty()
66    }
67
68    /// Converts this aggregate error into its collected issues.
69    #[inline]
70    #[must_use]
71    pub fn into_issues(self) -> Vec<MetadataError> {
72        self.issues
73    }
74}
75
76impl fmt::Display for MetadataValidationError {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        write!(f, "{} metadata validation issue(s)", self.issues.len())?;
79        for (index, issue) in self.issues.iter().enumerate() {
80            write!(f, "; {}: {issue}", index + 1)?;
81        }
82        Ok(())
83    }
84}
85
86impl std::error::Error for MetadataValidationError {}