#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum ApiProtocol {
#[default]
OpenAiChat,
Anthropic,
}
impl ApiProtocol {
pub fn path(&self) -> &'static str {
match self {
Self::OpenAiChat => "/chat/completions",
Self::Anthropic => "/messages",
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::OpenAiChat => "openai",
Self::Anthropic => "anthropic",
}
}
pub fn from_wire(raw: &str) -> Option<Self> {
match raw.to_ascii_lowercase().as_str() {
"openai" | "openai-chat" | "openai_chat" => Some(Self::OpenAiChat),
"anthropic" => Some(Self::Anthropic),
_ => None,
}
}
}
impl std::fmt::Display for ApiProtocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_is_openai_chat() {
assert_eq!(ApiProtocol::default(), ApiProtocol::OpenAiChat);
}
#[test]
fn each_protocol_has_its_own_path() {
assert_eq!(ApiProtocol::OpenAiChat.path(), "/chat/completions");
assert_eq!(ApiProtocol::Anthropic.path(), "/messages");
}
#[test]
fn each_protocol_has_its_own_name() {
assert_eq!(ApiProtocol::OpenAiChat.as_str(), "openai");
assert_eq!(ApiProtocol::Anthropic.as_str(), "anthropic");
}
#[test]
fn from_wire_is_case_insensitive() {
assert_eq!(
ApiProtocol::from_wire("ANTHROPIC"),
Some(ApiProtocol::Anthropic)
);
assert_eq!(
ApiProtocol::from_wire("OpenAI"),
Some(ApiProtocol::OpenAiChat)
);
}
#[test]
fn from_wire_accepts_every_spelling_of_openai() {
for spelling in ["openai", "openai-chat", "openai_chat"] {
assert_eq!(
ApiProtocol::from_wire(spelling),
Some(ApiProtocol::OpenAiChat),
"{spelling} should parse"
);
}
}
#[test]
fn from_wire_rejects_an_unknown_protocol() {
assert_eq!(ApiProtocol::from_wire("cohere"), None);
assert_eq!(ApiProtocol::from_wire(""), None);
}
#[test]
fn display_matches_as_str() {
assert_eq!(ApiProtocol::Anthropic.to_string(), "anthropic");
assert_eq!(ApiProtocol::OpenAiChat.to_string(), "openai");
}
#[test]
fn from_wire_round_trips_as_str() {
for protocol in [ApiProtocol::OpenAiChat, ApiProtocol::Anthropic] {
assert_eq!(ApiProtocol::from_wire(protocol.as_str()), Some(protocol));
}
}
}