Skip to main content

qubit_spi/
provider_create_error.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! Provider-level service creation errors.
11
12use std::error::Error;
13use std::fmt::{
14    Display,
15    Formatter,
16    Result as FmtResult,
17};
18use std::sync::Arc;
19
20/// Error returned by one provider while creating a service.
21#[derive(Debug, Clone)]
22pub enum ProviderCreateError {
23    /// The provider discovered at creation time that it cannot be used.
24    Unavailable {
25        /// Human-readable unavailability reason.
26        reason: String,
27        /// Lower-level cause, when the provider can expose one.
28        source: Option<Arc<dyn Error + Send + Sync + 'static>>,
29    },
30    /// The provider failed while creating the service.
31    Failed {
32        /// Human-readable failure reason.
33        reason: String,
34        /// Lower-level cause, when the provider can expose one.
35        source: Option<Arc<dyn Error + Send + Sync + 'static>>,
36    },
37}
38
39impl ProviderCreateError {
40    /// Creates an unavailable-provider error.
41    ///
42    /// # Parameters
43    /// - `reason`: Human-readable unavailability reason.
44    ///
45    /// # Returns
46    /// Provider creation error.
47    #[inline]
48    pub fn unavailable(reason: &str) -> Self {
49        Self::Unavailable {
50            reason: reason.to_owned(),
51            source: None,
52        }
53    }
54
55    /// Creates an unavailable-provider error with a source error.
56    ///
57    /// # Parameters
58    /// - `reason`: Human-readable unavailability reason.
59    /// - `source`: Lower-level cause that made the provider unavailable.
60    ///
61    /// # Returns
62    /// Provider creation error preserving the supplied source.
63    #[inline]
64    pub fn unavailable_with_source<E>(reason: &str, source: E) -> Self
65    where
66        E: Error + Send + Sync + 'static,
67    {
68        Self::Unavailable {
69            reason: reason.to_owned(),
70            source: Some(Arc::new(source)),
71        }
72    }
73
74    /// Creates a provider failure error.
75    ///
76    /// # Parameters
77    /// - `reason`: Human-readable failure reason.
78    ///
79    /// # Returns
80    /// Provider creation error.
81    #[inline]
82    pub fn failed(reason: &str) -> Self {
83        Self::Failed {
84            reason: reason.to_owned(),
85            source: None,
86        }
87    }
88
89    /// Creates a provider failure error with a source error.
90    ///
91    /// # Parameters
92    /// - `reason`: Human-readable failure reason.
93    /// - `source`: Lower-level cause that made service creation fail.
94    ///
95    /// # Returns
96    /// Provider creation error preserving the supplied source.
97    #[inline]
98    pub fn failed_with_source<E>(reason: &str, source: E) -> Self
99    where
100        E: Error + Send + Sync + 'static,
101    {
102        Self::Failed {
103            reason: reason.to_owned(),
104            source: Some(Arc::new(source)),
105        }
106    }
107
108    /// Gets the provider-level reason.
109    ///
110    /// # Returns
111    /// Human-readable reason carried by this error.
112    #[inline]
113    pub fn reason(&self) -> &str {
114        match self {
115            Self::Unavailable { reason, .. } | Self::Failed { reason, .. } => reason,
116        }
117    }
118
119    /// Tells whether this error represents provider unavailability.
120    ///
121    /// # Returns
122    /// `true` when the provider reported itself unavailable.
123    #[inline]
124    pub(crate) fn is_unavailable(&self) -> bool {
125        matches!(self, Self::Unavailable { .. })
126    }
127
128    /// Gets the lower-level source error.
129    ///
130    /// # Returns
131    /// `Some` source error when one was supplied, or `None` otherwise.
132    #[inline]
133    fn source_error(&self) -> Option<&(dyn Error + 'static)> {
134        match self {
135            Self::Unavailable { source, .. } | Self::Failed { source, .. } => source
136                .as_deref()
137                .map(|source| source as &(dyn Error + 'static)),
138        }
139    }
140}
141
142impl Display for ProviderCreateError {
143    #[inline]
144    fn fmt(&self, formatter: &mut Formatter<'_>) -> FmtResult {
145        match self {
146            Self::Unavailable { reason, .. } => {
147                write!(formatter, "provider is unavailable: {reason}")
148            }
149            Self::Failed { reason, .. } => {
150                write!(formatter, "provider failed to create service: {reason}")
151            }
152        }
153    }
154}
155
156impl Error for ProviderCreateError {
157    #[inline]
158    fn source(&self) -> Option<&(dyn Error + 'static)> {
159        self.source_error()
160    }
161}