LazyBoy2/crates/grokboy-core/src/config.rs

57 lines
1.6 KiB
Rust
Raw Normal View History

use std::env;
#[derive(Debug, Clone)]
pub struct Config {
pub api_key: String,
pub base_url: String,
pub model: String,
}
impl Config {
/// Resolve from environment. Prefers GROKBOY_*, then XAI_*, then OPENAI_*.
pub fn from_env() -> Result<Self, String> {
let api_key = env::var("GROKBOY_API_KEY")
.or_else(|_| env::var("XAI_API_KEY"))
.or_else(|_| env::var("OPENAI_API_KEY"))
.map_err(|_| {
"missing API key: set GROKBOY_API_KEY (or XAI_API_KEY / OPENAI_API_KEY)".to_string()
})?;
if api_key.trim().is_empty() {
return Err("API key is empty".into());
}
let base_url = env::var("GROKBOY_BASE_URL")
.or_else(|_| env::var("OPENAI_BASE_URL"))
.unwrap_or_else(|_| "https://api.x.ai/v1".into());
let model = env::var("GROKBOY_MODEL").unwrap_or_else(|_| "grok-4.6".into());
Ok(Self {
api_key,
base_url: base_url.trim_end_matches('/').to_string(),
model,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_model_is_grok_4_6() {
let cfg = Config {
api_key: "x".into(),
base_url: "https://api.x.ai/v1".into(),
model: "grok-4.6".into(),
};
assert_eq!(cfg.model, "grok-4.6");
}
#[test]
fn rejects_missing_key() {
let _ = Config {
api_key: "x".into(),
base_url: "https://api.x.ai/v1".into(),
model: "grok-4.6".into(),
};
}
}