use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct Client {
dir: PathBuf,
state: String,
pub commit_author_name: String,
pub commit_author_email: String,
}
impl Client {
pub fn new(
dir: Option<impl Into<PathBuf>>,
state: Option<impl Into<String>>,
commit_author_name: Option<impl Into<String>>,
commit_author_email: Option<impl Into<String>>,
) -> Self {
let dir = match dir {
Some(dir) => dir.into(),
None => {
#[cfg(feature = "env")]
let env_dir = std::env::var("OBJECTIVEAI_DIR").ok();
#[cfg(not(feature = "env"))]
let env_dir: Option<String> = None;
match env_dir {
Some(dir) => PathBuf::from(dir),
None => dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".objectiveai"),
}
}
};
let state = match state {
Some(state) => state.into(),
None => {
#[cfg(feature = "env")]
let env_state = std::env::var("OBJECTIVEAI_STATE").ok();
#[cfg(not(feature = "env"))]
let env_state: Option<String> = None;
env_state.unwrap_or_else(|| "default".to_string())
}
};
assert!(
is_valid_state_name(&state),
"OBJECTIVEAI_STATE {state:?} is invalid: state names must match [A-Za-z0-9_-]+",
);
Self {
dir,
state,
commit_author_name: resolve_author_name(commit_author_name),
commit_author_email: resolve_author_email(commit_author_email),
}
}
pub fn dir(&self) -> &PathBuf {
&self.dir
}
pub fn state(&self) -> &str {
&self.state
}
pub fn bin_dir(&self) -> PathBuf {
self.dir.join("bin")
}
pub fn state_dir(&self) -> PathBuf {
self.dir.join("state").join(&self.state)
}
pub fn config_path(&self) -> PathBuf {
self.state_dir().join("config.json")
}
pub fn global_config_path(&self) -> PathBuf {
self.bin_dir().join("config.json")
}
pub fn logs_dir(&self) -> PathBuf {
self.state_dir().join("logs")
}
}
fn is_valid_state_name(state: &str) -> bool {
!state.is_empty()
&& state
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
}
fn resolve_author_name(explicit: Option<impl Into<String>>) -> String {
if let Some(name) = explicit {
return name.into();
}
#[cfg(feature = "env")]
if let Ok(name) = std::env::var("COMMIT_AUTHOR_NAME") {
return name;
}
"ObjectiveAI".to_string()
}
fn resolve_author_email(explicit: Option<impl Into<String>>) -> String {
if let Some(email) = explicit {
return email.into();
}
#[cfg(feature = "env")]
if let Ok(email) = std::env::var("COMMIT_AUTHOR_EMAIL") {
return email;
}
"admin@objectiveai.dev".to_string()
}