#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mapping {
Exact,
Aliased(&'static str),
Manual,
}
impl Mapping {
#[must_use]
pub fn upstream_key(&self) -> Option<&'static str> {
match self {
Mapping::Exact => None,
Mapping::Aliased(k) => Some(k),
Mapping::Manual => None,
}
}
}
#[must_use]
pub fn resolve(catalog_id: &str) -> Mapping {
match catalog_id {
"openai" | "zai" | "minimax" | "minimax-cn" | "deepseek" | "alibaba" | "alibaba-cn"
| "lmstudio" => Mapping::Exact,
"gemini" => Mapping::Aliased("google"),
"zai-cn" => Mapping::Aliased("zai"),
"zai-coding" | "zai-cn-coding" => Mapping::Aliased("zai-coding-plan"),
"kimi" => Mapping::Aliased("kimi-for-coding"),
"moonshot" => Mapping::Aliased("moonshotai"),
"alibaba-us" => Mapping::Aliased("alibaba"),
_ => Mapping::Manual,
}
}
#[cfg(test)]
mod tests {
use super::*;
const EXACT: &[&str] = &[
"openai",
"zai",
"minimax",
"minimax-cn",
"deepseek",
"alibaba",
"alibaba-cn",
"lmstudio",
];
const MANUAL: &[&str] = &["native", "ve", "mimo", "ollama", "llamacpp"];
#[test]
fn test_exact_matches() {
for &id in EXACT {
assert_eq!(resolve(id), Mapping::Exact, "{id} should be Exact");
}
}
#[test]
fn test_aliased_matches() {
assert_eq!(resolve("gemini"), Mapping::Aliased("google"));
assert_eq!(resolve("zai-cn"), Mapping::Aliased("zai"));
assert_eq!(resolve("zai-coding"), Mapping::Aliased("zai-coding-plan"));
assert_eq!(
resolve("zai-cn-coding"),
Mapping::Aliased("zai-coding-plan")
);
assert_eq!(resolve("kimi"), Mapping::Aliased("kimi-for-coding"));
assert_eq!(resolve("moonshot"), Mapping::Aliased("moonshotai"));
assert_eq!(resolve("alibaba-us"), Mapping::Aliased("alibaba"));
}
#[test]
fn test_manual_matches() {
for &id in MANUAL {
assert_eq!(resolve(id), Mapping::Manual, "{id} should be Manual");
}
assert_eq!(resolve("totally-unknown"), Mapping::Manual);
}
#[test]
fn test_upstream_key_helper() {
assert_eq!(resolve("openai").upstream_key(), None); assert_eq!(resolve("gemini").upstream_key(), Some("google"));
assert_eq!(resolve("ollama").upstream_key(), None); }
#[test]
fn test_every_embedded_provider_is_classified() {
let ids = crate::provider::ProviderIndex::embedded().ids();
let aliased: &[&str] = &[
"gemini",
"zai-cn",
"zai-coding",
"zai-cn-coding",
"kimi",
"moonshot",
"alibaba-us",
];
for id in &ids {
let m = resolve(id);
let is_exact = EXACT.contains(&id.as_str());
let is_aliased = aliased.contains(&id.as_str());
let is_manual = MANUAL.contains(&id.as_str());
assert!(
match m {
Mapping::Exact => is_exact,
Mapping::Aliased(_) => is_aliased,
Mapping::Manual => is_manual,
},
"provider {id} resolved to {m:?} but is not in any known bucket — \
add a mapping decision in resolve()"
);
}
}
}