Skip to main content

aerocontext_core/
provider.rs

1//! The shared context-provider identity contract.
2
3/// Boxed error cause that keeps this crate free of transport dependencies.
4pub type ErrorCause = Box<dyn std::error::Error + Send + Sync>;
5
6/// Failure of a context-provider operation.
7#[derive(Debug, thiserror::Error)]
8#[non_exhaustive]
9pub enum ProviderError {
10    /// The network/HTTP layer failed before a usable response arrived.
11    #[error("transport failure while {context}")]
12    Transport {
13        /// What the adapter was doing, e.g. `"fetching METARs"`.
14        context: String,
15        /// Underlying transport error.
16        #[source]
17        cause: ErrorCause,
18    },
19    /// The provider answered, but with an error (HTTP status or in-band
20    /// fault).
21    #[error("provider error while {context}: {message}")]
22    Provider {
23        /// What the adapter was doing.
24        context: String,
25        /// Provider-supplied error message.
26        message: String,
27        /// HTTP status code, when the error surfaced at the HTTP layer.
28        status: Option<u16>,
29    },
30    /// The response arrived but could not be decoded.
31    #[error("undecodable response while {context}")]
32    Decode {
33        /// What the adapter was doing.
34        context: String,
35        /// Underlying decode error.
36        #[source]
37        cause: ErrorCause,
38    },
39    /// This source cannot serve the requested shape.
40    #[error("unsupported request: {reason}")]
41    Unsupported {
42        /// Why the request cannot be served, e.g. an [`crate::Area`]
43        /// variant the provider has no equivalent for.
44        reason: String,
45    },
46}
47
48/// The shared identity of every context provider.
49///
50/// A provider implements this once, then one capability trait per kind of
51/// context it serves: [`crate::WeatherBriefingProvider`] today, and the
52/// stubbed [`crate::OwnshipStatusProvider`] / [`crate::ControlCommandProvider`]
53/// later. Splitting by capability (not by provider) keeps each consumer
54/// depending only on the context it actually needs, and lets a new source
55/// implement just the capabilities it offers.
56pub trait ContextProvider: Send + Sync {
57    /// Stable, lowercase identifier for this provider, e.g. `"awc"`.
58    fn name(&self) -> &str;
59}