Skip to main content

qubit_metadata/
metadata_error.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! [`MetadataError`] — failures from explicit metadata APIs and schema checks.
10
11use std::fmt;
12
13use qubit_common::DataType;
14use qubit_value::{Value, ValueError};
15
16/// Errors produced by explicit metadata accessors and schema validation.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum MetadataError {
19    /// The requested key does not exist.
20    MissingKey(String),
21    /// A stored value cannot be converted to the requested type.
22    TypeMismatch {
23        /// Metadata key being read or validated.
24        key: String,
25        /// Expected data type.
26        expected: DataType,
27        /// Actual stored data type.
28        actual: DataType,
29        /// Human-readable conversion or validation message.
30        message: String,
31    },
32    /// A required schema field is missing from a metadata object.
33    MissingRequiredField {
34        /// Required metadata key.
35        key: String,
36        /// Expected data type for the missing field.
37        expected: DataType,
38    },
39    /// A metadata object contains a key not accepted by the schema.
40    UnknownField {
41        /// Unknown metadata key.
42        key: String,
43    },
44    /// A filter references a key that is not defined by the schema.
45    UnknownFilterField {
46        /// Unknown filter key.
47        key: String,
48    },
49    /// A filter uses an operator that is not compatible with the field type.
50    InvalidFilterOperator {
51        /// Metadata key being filtered.
52        key: String,
53        /// Filter operator name.
54        operator: &'static str,
55        /// Field data type defined by the schema.
56        data_type: DataType,
57        /// Human-readable validation message.
58        message: String,
59    },
60}
61
62impl MetadataError {
63    /// Builds a conversion error for `key` using the requested type and stored value.
64    #[inline]
65    pub(crate) fn conversion_error(
66        key: &str,
67        expected: DataType,
68        value: &Value,
69        error: ValueError,
70    ) -> Self {
71        Self::TypeMismatch {
72            key: key.to_string(),
73            expected,
74            actual: value.data_type(),
75            message: error.to_string(),
76        }
77    }
78
79    /// Builds a schema type-mismatch error for `key`.
80    #[inline]
81    pub(crate) fn type_mismatch(key: &str, expected: DataType, actual: DataType) -> Self {
82        Self::TypeMismatch {
83            key: key.to_string(),
84            expected,
85            actual,
86            message: format!("expected {expected}, got {actual}"),
87        }
88    }
89}
90
91impl fmt::Display for MetadataError {
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        match self {
94            Self::MissingKey(key) => write!(f, "Metadata key not found: {key}"),
95            Self::TypeMismatch {
96                key,
97                expected,
98                actual,
99                message,
100            } => write!(
101                f,
102                "Metadata key '{key}' expected {expected} but actual {actual}: {message}"
103            ),
104            Self::MissingRequiredField { key, expected } => write!(
105                f,
106                "Required metadata key '{key}' is missing (expected {expected})"
107            ),
108            Self::UnknownField { key } => {
109                write!(f, "Metadata key '{key}' is not defined in schema")
110            }
111            Self::UnknownFilterField { key } => {
112                write!(
113                    f,
114                    "Metadata filter references key '{key}' not defined in schema"
115                )
116            }
117            Self::InvalidFilterOperator {
118                key,
119                operator,
120                data_type,
121                message,
122            } => write!(
123                f,
124                "Metadata filter operator '{operator}' is invalid for key '{key}' with type {data_type}: {message}"
125            ),
126        }
127    }
128}
129
130impl std::error::Error for MetadataError {}