use std::path::Path;
use std::path::PathBuf;
use crate::Env;
#[cfg(any(feature = "fs", feature = "process"))]
pub trait CurrentDirSetter {
fn set_current_dir(&mut self, path: PathBuf);
}
#[cfg(any(feature = "process", feature = "request"))]
pub trait EnvVarSetter {
fn set_var(&mut self, key: String, value: String);
fn remove_var(&mut self, key: &str);
}
#[cfg(feature = "process")]
pub trait ProcessSetter: CurrentDirSetter + EnvVarSetter {}
#[cfg(feature = "process")]
impl<T: CurrentDirSetter + EnvVarSetter> ProcessSetter for T {}
pub struct PlatformEnv<'a, E: Env> {
pub(crate) env: &'a mut E,
#[cfg(feature = "fs")]
pub(crate) fs: &'a mut (dyn CurrentDirSetter + Send + Sync),
#[cfg(feature = "process")]
pub(crate) process: &'a mut (dyn ProcessSetter + Send + Sync),
#[cfg(feature = "request")]
pub(crate) request: &'a mut (dyn EnvVarSetter + Send + Sync),
}
impl<'a, E: Env> Env for PlatformEnv<'a, E> {
fn args(&self) -> crate::EnvArgs<'_> {
self.env.args()
}
fn current_dir(&self) -> &Path {
self.env.current_dir()
}
fn current_exe(&self) -> &Path {
self.env.current_exe()
}
fn home_dir(&self) -> &Path {
self.env.home_dir()
}
fn remove_var<T: AsRef<str>>(&mut self, key: T) -> Option<String> {
#[cfg(feature = "process")]
self.process.remove_var(key.as_ref());
#[cfg(feature = "request")]
self.request.remove_var(key.as_ref());
self.env.remove_var(key)
}
fn set_current_dir<T: Into<PathBuf>>(&mut self, path: T) -> PathBuf {
let old = self.env.set_current_dir(path);
#[cfg(feature = "fs")]
self.fs
.set_current_dir(self.env.current_dir().to_path_buf());
#[cfg(feature = "process")]
self.process
.set_current_dir(self.env.current_dir().to_path_buf());
old
}
fn set_var<T: Into<String>, U: Into<String>>(&mut self, key: T, value: U) -> Option<String> {
let key = key.into();
let value = value.into();
#[cfg(feature = "process")]
self.process.set_var(key.clone(), value.clone());
#[cfg(feature = "request")]
self.request.set_var(key.clone(), value.clone());
self.env.set_var(key, value)
}
fn tmp_dir(&self) -> &Path {
self.env.tmp_dir()
}
fn var<T: AsRef<str>>(&self, key: T) -> Option<&str> {
self.env.var(key)
}
fn vars(&self) -> crate::EnvVars<'_> {
self.env.vars()
}
}