use std::env;
use std::fs;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
const DEFAULT_BASE_URL: &str = "https://biolib.com";
#[derive(Debug, Clone)]
pub struct Config {
pub base_url: String,
pub api_token: Option<String>,
pub ca_bundle: Option<String>,
pub is_public_biolib: bool,
pub cloud_base_url: Option<String>,
pub cloud_job_storage_base_url: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct UserState {
pub refresh_token: Option<String>,
}
impl Config {
pub fn load() -> Self {
let base_url = env::var("BIOLIB_BASE_URL").unwrap_or_else(|_| DEFAULT_BASE_URL.to_string());
let api_token = env::var("BIOLIB_TOKEN").ok();
let ca_bundle = env::var("BIOLIB_CA_BUNDLE")
.ok()
.or_else(|| env::var("REQUESTS_CA_BUNDLE").ok())
.or_else(|| env::var("SSL_CERT_FILE").ok());
let is_public_biolib = base_url.ends_with("biolib.com")
|| env::var("BIOLIB_ENVIRONMENT_IS_PUBLIC_BIOLIB")
.map(|v| v.eq_ignore_ascii_case("true"))
.unwrap_or(false);
let cloud_base_url = env::var("BIOLIB_CLOUD_BASE_URL")
.ok()
.filter(|v| !v.is_empty());
let cloud_job_storage_base_url = env::var("BIOLIB_CLOUD_JOB_STORAGE_BASE_URL")
.ok()
.filter(|v| !v.is_empty());
Self {
base_url,
api_token,
ca_bundle,
is_public_biolib,
cloud_base_url,
cloud_job_storage_base_url,
}
}
pub fn state_file_path() -> PathBuf {
let home = env::var("HOME")
.map(PathBuf::from)
.unwrap_or_else(|_| PathBuf::from("."));
home.join(".biolib").join("state.json")
}
pub fn load_user_state() -> UserState {
let path = Self::state_file_path();
if path.exists() {
if let Ok(content) = fs::read_to_string(&path) {
if let Ok(state) = serde_json::from_str(&content) {
return state;
}
}
}
UserState::default()
}
pub fn save_user_state(state: &UserState) -> crate::Result<()> {
let path = Self::state_file_path();
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
let content = serde_json::to_string_pretty(state)?;
fs::write(path, content)?;
Ok(())
}
}