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

48 lines
1.4 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".into());
Ok(Self {
api_key,
base_url: base_url.trim_end_matches('/').to_string(),
model,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rejects_missing_key() {
// Ensure we don't panic; actual env may have keys in CI — just type-check path.
let _ = Config {
api_key: "x".into(),
base_url: "https://api.x.ai/v1".into(),
model: "grok-4".into(),
};
}
}