Skip to main content

qubit_spi/
lib.rs

1//! # Qubit SPI
2//!
3//! Typed service provider infrastructure for Qubit Rust crates.
4//!
5//! This crate provides the small service-provider layer that many Qubit crates
6//! need when a base crate owns a trait and extension crates provide optional
7//! implementations. A [`ServiceProvider`] supplies stable names, aliases,
8//! runtime availability, priority, and a factory method. A
9//! [`ProviderRegistry`] resolves providers by name, by automatic priority, or
10//! through an explicit fallback chain.
11//!
12//! # Examples
13//!
14//! Register a provider and create a service by name:
15//!
16//! ```rust
17//! use std::fmt::Debug;
18//!
19//! use qubit_spi::{
20//!     ProviderCreateError,
21//!     ProviderDescriptor,
22//!     ProviderRegistry,
23//!     ProviderRegistryError,
24//!     ServiceProvider,
25//!     ServiceSpec,
26//! };
27//!
28//! trait Greeter: Debug + Send + Sync {
29//!     fn greet(&self) -> &'static str;
30//! }
31//!
32//! #[derive(Debug)]
33//! struct EnglishGreeter;
34//!
35//! impl Greeter for EnglishGreeter {
36//!     fn greet(&self) -> &'static str {
37//!         "hello"
38//!     }
39//! }
40//!
41//! #[derive(Debug)]
42//! struct EnglishProvider;
43//!
44//! #[derive(Debug)]
45//! struct GreeterSpec;
46//!
47//! impl ServiceSpec for GreeterSpec {
48//!     type Config = ();
49//!     type Service = dyn Greeter;
50//! }
51//!
52//! impl ServiceProvider<GreeterSpec> for EnglishProvider {
53//!     fn descriptor(&self) -> Result<ProviderDescriptor, ProviderRegistryError> {
54//!         ProviderDescriptor::new("english")?.with_aliases(&["en"])
55//!     }
56//!
57//!     fn create_box(&self, _config: &()) -> Result<Box<dyn Greeter>, ProviderCreateError> {
58//!         Ok(Box::new(EnglishGreeter))
59//!     }
60//! }
61//!
62//! let mut registry = ProviderRegistry::<GreeterSpec>::new();
63//! registry
64//!     .register(EnglishProvider)
65//!     .expect("provider names should be unique");
66//!
67//! let greeter = registry
68//!     .create_box("en", &())
69//!     .expect("registered provider should create a greeter");
70//! assert_eq!("hello", greeter.greet());
71//! ```
72
73mod provider_availability;
74mod provider_create_error;
75mod provider_descriptor;
76mod provider_failure;
77mod provider_name;
78mod provider_registry;
79mod provider_registry_error;
80mod provider_selection;
81mod service_provider;
82mod service_spec;
83
84pub use provider_availability::ProviderAvailability;
85pub use provider_create_error::ProviderCreateError;
86pub use provider_descriptor::ProviderDescriptor;
87pub use provider_failure::ProviderFailure;
88pub use provider_name::ProviderName;
89pub use provider_registry::ProviderRegistry;
90pub use provider_registry_error::ProviderRegistryError;
91pub use provider_selection::ProviderSelection;
92pub use service_provider::ServiceProvider;
93pub use service_spec::ServiceSpec;