Skip to main content

codewhale_config/route/
errors.rs

1//! Route resolution errors (#3384).
2//!
3//! `thiserror` is not a dependency of this crate, so [`Display`] and
4//! [`std::error::Error`] are hand-implemented. No new dependency is added.
5
6use std::fmt;
7
8use super::ids::ProviderId;
9
10/// Why a [`super::resolver::RouteResolver`] could not produce a candidate.
11#[derive(Debug, Clone)]
12pub enum RouteError {
13    /// The requested model selector was empty.
14    EmptyModel,
15    /// The named provider could not be resolved.
16    InvalidProvider(String),
17    /// A model matched multiple providers; the caller must disambiguate.
18    AmbiguousModel(Vec<ProviderId>),
19    /// A clearly-foreign model was requested for a strict direct provider.
20    ForeignModelForDirectProvider {
21        /// The strict direct provider that rejected the model.
22        provider: ProviderId,
23        /// The foreign model selector that was rejected.
24        model: String,
25    },
26}
27
28impl fmt::Display for RouteError {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match self {
31            Self::EmptyModel => write!(f, "model selector was empty"),
32            Self::InvalidProvider(name) => write!(f, "invalid provider: {name}"),
33            Self::AmbiguousModel(providers) => {
34                let names: Vec<&str> = providers.iter().map(ProviderId::as_str).collect();
35                write!(
36                    f,
37                    "model matches multiple providers ({}); specify a provider",
38                    names.join(", ")
39                )
40            }
41            Self::ForeignModelForDirectProvider { provider, model } => write!(
42                f,
43                "model {model:?} is not served by direct provider {}",
44                provider.as_str()
45            ),
46        }
47    }
48}
49
50impl std::error::Error for RouteError {}