110 lines
3.0 KiB
Rust
110 lines
3.0 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
use std::{env, ffi::OsString, fs, io, path::PathBuf};
|
|
|
|
#[cfg(feature = "log-facade")]
|
|
mod log;
|
|
#[cfg(feature = "log-facade")]
|
|
pub use self::log::*;
|
|
|
|
pub(crate) fn cache_dir() -> Option<OsString> {
|
|
let dir = env::var_os("STATE_DIRECTORY").or_else(|| {
|
|
env::var_os("HOME").and_then(|dir| {
|
|
let mut dir: PathBuf = dir.into();
|
|
dir.push(".cache");
|
|
dir.push("rebterlai");
|
|
Some(OsString::from(dir))
|
|
})
|
|
});
|
|
dir
|
|
}
|
|
|
|
pub(crate) fn state_file(name: &str) -> Option<PathBuf> {
|
|
let mut dir: PathBuf = cache_dir()?.into();
|
|
dir.push(&format!("{}.json", name));
|
|
Some(dir)
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug)]
|
|
pub struct Config {
|
|
private_id: String,
|
|
public_id: String,
|
|
}
|
|
|
|
impl Config {
|
|
pub fn new() -> Self {
|
|
let private_id = logtail::PrivateID::new();
|
|
|
|
Self {
|
|
private_id: private_id.as_hex(),
|
|
public_id: private_id.as_public().as_hex(),
|
|
}
|
|
}
|
|
|
|
pub fn load<S>(collection: S) -> io::Result<Self>
|
|
where
|
|
S: Into<String>,
|
|
{
|
|
let dir = cache_dir()
|
|
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "can't find directory"))?;
|
|
if let Err(_) = fs::metadata(&dir) {
|
|
fs::create_dir_all(&dir)?;
|
|
}
|
|
println!("{:?}", dir);
|
|
|
|
let fname = state_file(&collection.into()).ok_or_else(|| {
|
|
io::Error::new(
|
|
io::ErrorKind::InvalidInput,
|
|
"can't derive logtail config filename",
|
|
)
|
|
})?;
|
|
match fs::metadata(&fname) {
|
|
Ok(_) => {
|
|
let fin = fs::File::open(&fname)?;
|
|
let cfg = serde_json::from_reader(io::BufReader::new(fin))
|
|
.or_else(|why| Err(io::Error::new(io::ErrorKind::Other, why)))?;
|
|
Ok(cfg)
|
|
}
|
|
Err(_) => {
|
|
let cfg = Self::new();
|
|
let mut fout = fs::File::create(&fname)?;
|
|
serde_json::to_writer(&mut fout, &cfg)
|
|
.or_else(|why| Err(io::Error::new(io::ErrorKind::Other, why)))?;
|
|
Ok(cfg)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use tempdir::TempDir;
|
|
|
|
#[test]
|
|
#[serial_test::serial]
|
|
fn cache_dir() {
|
|
let home = TempDir::new("cache").unwrap();
|
|
std::env::set_var("STATE_DIRECTORY", home.path().to_str().unwrap());
|
|
let dir = super::cache_dir();
|
|
|
|
assert!(dir.is_some());
|
|
assert_eq!(dir.unwrap(), home.path().to_str().unwrap());
|
|
|
|
home.close().unwrap();
|
|
}
|
|
|
|
#[test]
|
|
#[serial_test::serial]
|
|
fn new_and_load() {
|
|
let home = TempDir::new("cache").unwrap();
|
|
std::env::set_var("STATE_DIRECTORY", home.path().to_str().unwrap());
|
|
|
|
let cfg = Config::load("foo.bar").unwrap();
|
|
let cfg2 = Config::load("foo.bar").unwrap();
|
|
|
|
assert_eq!(cfg, cfg2);
|
|
|
|
home.close().unwrap();
|
|
}
|
|
}
|