typesafe-jev 0.2.0

Typed client for TypeSafe's System One API and its Jev model: calibrated Noul, Choice and Score answers about JSON state, with retries, adaptive concurrency and usage accounting
Documentation
use std::fmt;

/// Why a client could not be built, or a request could not be answered.
///
/// Transient failures (connection errors, HTTP 429, 5xx) are retried inside
/// [`Client::ask`](crate::Client::ask) and only surface as [`Error::Api`] once the retries are
/// spent. The other variants are returned at once, because retrying cannot help.
///
/// The enum is `#[non_exhaustive]`: a later version may tell more failures apart, so a `match`
/// needs a wildcard arm. [`Error::message`] and `Display` give the text of any variant.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum Error {
    /// Missing, blank, unsendable or rejected credentials (HTTP 401 or 403).
    Auth(String),
    /// The request exceeded the model's context (`max_tokens_exceeded`, or HTTP 413). Ask fewer
    /// questions, or about less state, and retry.
    TokenLimit(String),
    /// A request the API would not evaluate: a state that does not serialize to JSON, or a body
    /// the API refused as malformed (HTTP 422), such as a [`Score`](crate::Score) with a single
    /// level or a state that is a bare number. The message quotes what the API objected to.
    InvalidRequest(String),
    /// A [`Config`](crate::Config) no request could be sent with: a base URL that is not an
    /// absolute `http` or `https` URL, or a user agent that is not a valid header value.
    /// Reported by [`Client::new`](crate::Client::new), before anything is sent.
    InvalidConfig(String),
    /// Anything else: an unreadable response, an unexpected status, or retries exhausted.
    Api(String),
}

impl Error {
    /// The message, without the variant.
    pub fn message(&self) -> &str {
        let (Error::Auth(m) | Error::TokenLimit(m) | Error::InvalidRequest(m) | Error::InvalidConfig(m) | Error::Api(m)) = self;
        m
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_str(self.message())
    }
}

impl std::error::Error for Error {}