Skip to main content

qubit_progress/error/
configuration_error.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//! Errors found while validating fixed progress configuration.
9// qubit-style: allow source-test-pair
10
11use std::{
12    error::Error,
13    fmt,
14};
15
16/// Invalid fixed metadata supplied to a progress operation.
17#[derive(Clone, Debug, Eq, PartialEq)]
18#[non_exhaustive]
19pub enum ConfigurationError {
20    /// An operation was started without metrics.
21    NoMetrics,
22    /// A metric ID is empty or whitespace only.
23    EmptyMetricId {
24        /// Zero-based metric position in the builder.
25        index: usize,
26    },
27    /// A metric name is empty or whitespace only.
28    EmptyMetricName {
29        /// ID of the malformed metric.
30        metric_id: String,
31    },
32    /// Two configured metrics have the same ID.
33    DuplicateMetricId {
34        /// Duplicated stable metric ID.
35        metric_id: String,
36    },
37    /// An operation attribute key is empty or whitespace only.
38    EmptyAttributeKey {
39        /// Malformed attribute key.
40        key: String,
41    },
42    /// A stage ID is empty or whitespace only.
43    EmptyStageId,
44    /// A stage name is empty or whitespace only.
45    EmptyStageName,
46    /// Stage position and total were not supplied together.
47    IncompleteStagePosition,
48    /// Stage position is outside its one-based total range.
49    InvalidStagePosition {
50        /// Invalid one-based position.
51        position: u64,
52        /// Declared number of stages.
53        total: u64,
54    },
55}
56
57impl fmt::Display for ConfigurationError {
58    /// Formats a concise configuration explanation.
59    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
60        match self {
61            Self::NoMetrics => formatter
62                .write_str("a progress operation requires at least one metric"),
63            Self::EmptyMetricId { index } => {
64                write!(formatter, "metric at index {index} has an empty ID")
65            }
66            Self::EmptyMetricName { metric_id } => {
67                write!(formatter, "metric {metric_id:?} has an empty name")
68            }
69            Self::DuplicateMetricId { metric_id } => {
70                write!(formatter, "metric ID {metric_id:?} is duplicated")
71            }
72            Self::EmptyAttributeKey { key } => {
73                write!(formatter, "operation attribute key {key:?} is empty")
74            }
75            Self::EmptyStageId => formatter.write_str("stage ID is empty"),
76            Self::EmptyStageName => formatter.write_str("stage name is empty"),
77            Self::IncompleteStagePosition => formatter.write_str(
78                "stage position and total must be supplied together",
79            ),
80            Self::InvalidStagePosition { position, total } => write!(
81                formatter,
82                "stage position {position} is outside 1..={total}"
83            ),
84        }
85    }
86}
87
88impl Error for ConfigurationError {}