qubit_spi/provider_registry_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//! Error type for provider registration and selection.
11
12use thiserror::Error;
13
14use crate::{
15 ProviderFailure,
16 ProviderName,
17};
18
19/// Error returned by provider registries.
20#[derive(Debug, Clone, Error)]
21pub enum ProviderRegistryError {
22 /// A provider id, alias, or selector is empty after trimming.
23 #[error("provider name must not be empty")]
24 EmptyProviderName,
25 /// A provider name contains unsupported characters.
26 #[error("invalid provider name '{name}': {reason}")]
27 InvalidProviderName {
28 /// Invalid provider name after trimming.
29 name: String,
30 /// Human-readable validation failure reason.
31 reason: String,
32 },
33 /// A provider id or alias conflicts with an already registered name.
34 #[error("duplicate provider name: {name}")]
35 DuplicateProviderName {
36 /// Conflicting provider name.
37 name: ProviderName,
38 },
39 /// A named selection repeats a provider candidate.
40 #[error("duplicate provider candidate in selection: {name}")]
41 DuplicateProviderCandidate {
42 /// Repeated provider candidate name.
43 name: ProviderName,
44 },
45 /// No registered provider matches the requested selector.
46 #[error("unknown provider: {name}")]
47 UnknownProvider {
48 /// Requested provider selector.
49 name: ProviderName,
50 },
51 /// The selected provider is not available in the current environment.
52 #[error("provider '{name}' is unavailable: {}", .source.reason())]
53 ProviderUnavailable {
54 /// Requested provider selector.
55 name: ProviderName,
56 /// Provider-level unavailability error.
57 #[source]
58 source: crate::ProviderCreateError,
59 },
60 /// The selected provider failed while creating a service.
61 #[error("provider '{name}' failed to create service: {}", .source.reason())]
62 ProviderCreate {
63 /// Requested provider selector.
64 name: ProviderName,
65 /// Provider-level creation error.
66 #[source]
67 source: crate::ProviderCreateError,
68 },
69 /// All configured provider candidates failed.
70 #[error(
71 "no available provider; candidate failures: {}",
72 format_provider_failures(.failures)
73 )]
74 NoAvailableProvider {
75 /// Candidate failures in the order they were tried.
76 failures: Vec<ProviderFailure>,
77 },
78 /// No providers are registered.
79 #[error("provider registry is empty")]
80 EmptyRegistry,
81}
82
83/// Formats ordered fallback candidate failures.
84///
85/// # Parameters
86/// - `failures`: Candidate failures in the order they were tried.
87///
88/// # Returns
89/// Candidate failure messages joined by `; `.
90fn format_provider_failures(failures: &[ProviderFailure]) -> String {
91 failures
92 .iter()
93 .map(ToString::to_string)
94 .collect::<Vec<_>>()
95 .join("; ")
96}