use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ProviderDef {
pub name: String,
#[serde(default)]
pub label: String,
#[serde(default)]
pub env_var: String,
#[serde(default)]
pub model: String,
#[serde(default)]
pub base_url: String,
#[serde(default)]
pub user_agent: String,
#[serde(default)]
pub needs_key: bool,
#[serde(default = "default_api_type")]
pub api_type: String,
#[serde(default)]
pub name_zh: String,
#[serde(default)]
pub name_en: String,
#[serde(default)]
pub tag_zh: String,
#[serde(default)]
pub tag_en: String,
#[serde(default)]
pub key_label: String,
#[serde(default)]
pub key_placeholder: String,
#[serde(default)]
pub is_url: bool,
#[serde(default)]
pub has_base_url: bool,
#[serde(default)]
pub order_zh: i32,
#[serde(default)]
pub order_en: i32,
}
fn default_api_type() -> String {
"openai".to_owned()
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChannelFieldDef {
pub key: String,
#[serde(default)]
pub prompt: String,
#[serde(default)]
pub secret: bool,
#[serde(default)]
pub placeholder: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ChannelDef {
pub name: String,
#[serde(default)]
pub label: String,
#[serde(default)]
pub fields: Vec<ChannelFieldDef>,
#[serde(default)]
pub login: bool,
#[serde(default)]
pub multi_account: bool,
#[serde(default)]
pub name_zh: String,
#[serde(default)]
pub icon: String,
#[serde(default)]
pub has_qr: bool,
#[serde(default)]
pub qr_label_zh: String,
#[serde(default)]
pub qr_label_en: String,
#[serde(default)]
pub order_zh: i32,
#[serde(default)]
pub order_en: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SearchEngineDef {
pub name: String,
#[serde(default)]
pub label: String,
#[serde(default)]
pub url: String,
#[serde(default)]
pub env_var: String,
#[serde(default)]
pub label_zh: String,
#[serde(default)]
pub label_en: String,
#[serde(default)]
pub needs_key: bool,
#[serde(default)]
pub order: i32,
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Catalog {
#[serde(default)]
pub providers: Vec<ProviderDef>,
#[serde(default)]
pub channels: Vec<ChannelDef>,
#[serde(default)]
pub search_engines: Vec<SearchEngineDef>,
}
impl Catalog {
pub fn from_toml_str(s: &str) -> Result<Self, toml::de::Error> {
toml::from_str(s)
}
}
pub fn load_catalog() -> Result<Catalog, toml::de::Error> {
Catalog::from_toml_str(&crate::loader::load_defaults_toml())
}
pub fn embedded_catalog() -> Catalog {
Catalog::from_toml_str(crate::loader::embedded_defaults_toml())
.expect("embedded defaults.toml is always valid")
}