Skip to main content

qubit_progress/error/
start_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 encountered while starting a progress operation.
9// qubit-style: allow source-test-pair
10
11use std::{
12    error::Error,
13    fmt,
14};
15
16use crate::error::{
17    ConfigurationError,
18    DeliveryError,
19    EmissionError,
20};
21
22/// Failure before a usable progress operation can be returned.
23#[derive(Clone, Debug)]
24#[non_exhaustive]
25pub enum StartError {
26    /// Fixed operation metadata is invalid.
27    InvalidConfiguration(ConfigurationError),
28    /// The process-local operation ID space is exhausted.
29    OperationIdExhausted,
30    /// Started was attempted but rejected by the reporter.
31    Delivery(DeliveryError),
32}
33
34impl fmt::Display for StartError {
35    /// Formats the start failure.
36    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match self {
38            Self::InvalidConfiguration(error) => error.fmt(formatter),
39            Self::OperationIdExhausted => {
40                formatter.write_str("progress operation IDs are exhausted")
41            }
42            Self::Delivery(error) => error.fmt(formatter),
43        }
44    }
45}
46
47impl Error for StartError {
48    /// Returns the nested configuration or delivery failure.
49    fn source(&self) -> Option<&(dyn Error + 'static)> {
50        match self {
51            Self::InvalidConfiguration(error) => Some(error),
52            Self::OperationIdExhausted => None,
53            Self::Delivery(error) => Some(error),
54        }
55    }
56}
57
58impl From<ConfigurationError> for StartError {
59    /// Converts configuration validation into a start failure.
60    fn from(error: ConfigurationError) -> Self {
61        Self::InvalidConfiguration(error)
62    }
63}
64
65impl From<EmissionError> for StartError {
66    /// Converts the only possible start-time emission failures.
67    fn from(error: EmissionError) -> Self {
68        match error {
69            EmissionError::Delivery(error) => Self::Delivery(error),
70            EmissionError::SequenceExhausted => Self::OperationIdExhausted,
71        }
72    }
73}