aerocontext-core 0.3.0

Provider-neutral aeronautical-context model and the pluggable ContextProvider contract
Documentation
//! The shared context-provider identity contract.

/// Boxed error cause that keeps this crate free of transport dependencies.
pub type ErrorCause = Box<dyn std::error::Error + Send + Sync>;

/// Failure of a context-provider operation.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum ProviderError {
    /// The network/HTTP layer failed before a usable response arrived.
    #[error("transport failure while {context}")]
    Transport {
        /// What the adapter was doing, e.g. `"fetching METARs"`.
        context: String,
        /// Underlying transport error.
        #[source]
        cause: ErrorCause,
    },
    /// The provider answered, but with an error (HTTP status or in-band
    /// fault).
    #[error("provider error while {context}: {message}")]
    Provider {
        /// What the adapter was doing.
        context: String,
        /// Provider-supplied error message.
        message: String,
        /// HTTP status code, when the error surfaced at the HTTP layer.
        status: Option<u16>,
    },
    /// The response arrived but could not be decoded.
    #[error("undecodable response while {context}")]
    Decode {
        /// What the adapter was doing.
        context: String,
        /// Underlying decode error.
        #[source]
        cause: ErrorCause,
    },
    /// This source cannot serve the requested shape.
    #[error("unsupported request: {reason}")]
    Unsupported {
        /// Why the request cannot be served, e.g. an [`crate::Area`]
        /// variant the provider has no equivalent for.
        reason: String,
    },
}

/// The shared identity of every context provider.
///
/// A provider implements this once, then one capability trait per kind of
/// context it serves: [`crate::WeatherBriefingProvider`] today, and the
/// stubbed [`crate::OwnshipStatusProvider`] / [`crate::ControlCommandProvider`]
/// later. Splitting by capability (not by provider) keeps each consumer
/// depending only on the context it actually needs, and lets a new source
/// implement just the capabilities it offers.
pub trait ContextProvider: Send + Sync {
    /// Stable, lowercase identifier for this provider, e.g. `"awc"`.
    fn name(&self) -> &str;
}