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