1use anyhow::Result;
2use serde::{Deserialize, Serialize};
3use std::fmt;
4use std::str::FromStr;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename_all = "lowercase")]
9pub enum Provider {
10 OpenAI,
11 Anthropic,
12}
13
14impl Provider {
15 pub fn as_str(&self) -> &'static str {
17 match self {
18 Provider::OpenAI => "openai",
19 Provider::Anthropic => "anthropic",
20 }
21 }
22
23 pub fn as_display(&self) -> String {
25 match self {
26 Provider::OpenAI => "OpenAI".to_string(),
27 Provider::Anthropic => "Anthropic".to_string(),
28 }
29 }
30
31 pub fn all() -> Vec<Provider> {
33 vec![Provider::OpenAI, Provider::Anthropic]
34 }
35
36 pub fn all_as_str() -> Vec<String> {
38 Self::all().iter().map(|p| p.as_str().to_string()).collect()
39 }
40}
41
42impl fmt::Display for Provider {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 write!(f, "{}", self.as_str())
45 }
46}
47
48impl FromStr for Provider {
49 type Err = anyhow::Error;
50
51 fn from_str(s: &str) -> Result<Self> {
52 match s.to_lowercase().as_str() {
53 "openai" => Ok(Provider::OpenAI),
54 "anthropic" => Ok(Provider::Anthropic),
55 _ => anyhow::bail!(
56 "Unknown provider: {}. Available: {}",
57 s,
58 Self::all_as_str().join(", ")
59 ),
60 }
61 }
62}