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}