#![warn(missing_docs)]
use std::path::{Path, PathBuf};
use crate::Result;
pub struct Context {
home: PathBuf,
lib: PathBuf,
ipc_policy: IPCPolicy,
ephemeral: bool,
cleanup: bool,
}
impl Clone for Context {
fn clone(&self) -> Self {
Context {
home: self.home.clone(),
lib: self.lib.clone(),
ipc_policy: self.ipc_policy,
ephemeral: self.ephemeral,
cleanup: false, }
}
}
impl Drop for Context {
fn drop(&mut self) {
use std::fs::remove_dir_all;
if self.ephemeral && self.cleanup {
let _ = remove_dir_all(&self.home);
}
}
}
fn prefix() -> PathBuf {
PathBuf::from(option_env!("PREFIX").unwrap_or("/usr/local"))
}
impl Context {
pub fn new() -> Result<Self> {
Self::configure().build()
}
pub fn configure() -> Config {
Config(Context {
home: PathBuf::from(""), lib: prefix().join("lib").join("sequoia"),
ipc_policy: IPCPolicy::Robust,
ephemeral: false,
cleanup: false,
})
}
pub fn home(&self) -> &Path {
&self.home
}
pub fn lib(&self) -> &Path {
&self.lib
}
pub fn ipc_policy(&self) -> &IPCPolicy {
&self.ipc_policy
}
pub fn ephemeral(&self) -> bool {
self.ephemeral
}
}
pub struct Config(Context);
impl Config {
pub fn build(self) -> Result<Context> {
let mut c = self.0;
let home_not_set = c.home == PathBuf::from("");
if c.ephemeral && home_not_set {
let tmp = tempfile::Builder::new().prefix("sequoia").tempdir()?;
c.home = tmp.into_path();
c.cleanup = true;
} else if home_not_set {
c.home = dirs::home_dir()
.ok_or_else(|| anyhow::anyhow!("Failed to get users home directory"))?
.join(".sequoia");
}
Ok(c)
}
pub fn home<P: AsRef<Path>>(mut self, home: P) -> Self {
self.set_home(home);
self
}
pub fn set_home<P: AsRef<Path>>(&mut self, home: P) -> PathBuf {
::std::mem::replace(&mut self.0.home, PathBuf::new().join(home))
}
pub fn lib<P: AsRef<Path>>(mut self, lib: P) -> Self {
self.set_lib(lib);
self
}
pub fn set_lib<P: AsRef<Path>>(&mut self, lib: P) -> PathBuf {
::std::mem::replace(&mut self.0.lib, PathBuf::new().join(lib))
}
pub fn ipc_policy(mut self, policy: IPCPolicy) -> Self {
self.set_ipc_policy(policy);
self
}
pub fn set_ipc_policy(&mut self, policy: IPCPolicy) -> IPCPolicy {
::std::mem::replace(&mut self.0.ipc_policy, policy)
}
pub fn ephemeral(mut self) -> Self {
self.set_ephemeral();
self
}
pub fn set_ephemeral(&mut self) -> bool {
::std::mem::replace(&mut self.0.ephemeral, true)
}
}
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum IPCPolicy {
External,
Internal,
Robust,
}
impl<'a> From<&'a IPCPolicy> for u8 {
fn from(policy: &IPCPolicy) -> Self {
match policy {
IPCPolicy::External => 0,
IPCPolicy::Internal => 1,
IPCPolicy::Robust => 2,
}
}
}
impl From<u8> for IPCPolicy {
fn from(policy: u8) -> Self {
match policy {
0 => IPCPolicy::External,
1 => IPCPolicy::Internal,
2 => IPCPolicy::Robust,
n => panic!("Bad IPC policy: {}", n),
}
}
}