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    /// A filter expression is structurally invalid.
61    InvalidFilterExpression {
62        /// Human-readable validation message.
63        message: String,
64    },
65}
66
67impl MetadataError {
68    /// Builds a conversion error for `key` using the requested type and stored value.
69    #[inline]
70    pub(crate) fn conversion_error(
71        key: &str,
72        expected: DataType,
73        value: &Value,
74        error: ValueError,
75    ) -> Self {
76        Self::TypeMismatch {
77            key: key.to_string(),
78            expected,
79            actual: value.data_type(),
80            message: error.to_string(),
81        }
82    }
83
84    /// Builds a schema type-mismatch error for `key`.
85    #[inline]
86    pub(crate) fn type_mismatch(key: &str, expected: DataType, actual: DataType) -> Self {
87        Self::TypeMismatch {
88            key: key.to_string(),
89            expected,
90            actual,
91            message: format!("expected {expected}, got {actual}"),
92        }
93    }
94}
95
96impl fmt::Display for MetadataError {
97    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        match self {
99            Self::MissingKey(key) => write!(f, "Metadata key not found: {key}"),
100            Self::TypeMismatch {
101                key,
102                expected,
103                actual,
104                message,
105            } => write!(
106                f,
107                "Metadata key '{key}' expected {expected} but actual {actual}: {message}"
108            ),
109            Self::MissingRequiredField { key, expected } => write!(
110                f,
111                "Required metadata key '{key}' is missing (expected {expected})"
112            ),
113            Self::UnknownField { key } => {
114                write!(f, "Metadata key '{key}' is not defined in schema")
115            }
116            Self::UnknownFilterField { key } => {
117                write!(
118                    f,
119                    "Metadata filter references key '{key}' not defined in schema"
120                )
121            }
122            Self::InvalidFilterOperator {
123                key,
124                operator,
125                data_type,
126                message,
127            } => write!(
128                f,
129                "Metadata filter operator '{operator}' is invalid for key '{key}' with type {data_type}: {message}"
130            ),
131            Self::InvalidFilterExpression { message } => {
132                write!(f, "Metadata filter expression is invalid: {message}")
133            }
134        }
135    }
136}
137
138impl std::error::Error for MetadataError {}