use env::{ExportedVariableEnvironment, VariableEnvironment, UnsetVariableEnvironment};
use std::collections::HashMap;
use std::fmt;
pub trait VarEnvRestorer<E: ?Sized + VariableEnvironment> {
fn reserve(&mut self, additional: usize);
#[deprecated(note = "Use `VarEnvRestorer2::set_exported_var2` instead")]
fn set_exported_var(&mut self, name: E::VarName, val: E::Var, exported: bool, env: &mut E);
fn unset_var(&mut self, name: E::VarName, env: &mut E);
fn backup(&mut self, key: E::VarName, env: &E);
fn restore(&mut self, env: &mut E);
}
impl<'a, T, E: ?Sized> VarEnvRestorer<E> for &'a mut T
where T: VarEnvRestorer<E>,
E: VariableEnvironment,
{
fn reserve(&mut self, additional: usize) {
(**self).reserve(additional);
}
#[allow(deprecated)]
fn set_exported_var(&mut self, name: E::VarName, val: E::Var, exported: bool, env: &mut E) {
(**self).set_exported_var(name, val, exported, env);
}
fn unset_var(&mut self, name: E::VarName, env: &mut E) {
(**self).unset_var(name, env);
}
fn backup(&mut self, key: E::VarName, env: &E) {
(**self).backup(key, env);
}
fn restore(&mut self, env: &mut E) {
(**self).restore(env);
}
}
pub trait VarEnvRestorer2<E: ?Sized + VariableEnvironment>: VarEnvRestorer<E> {
fn set_exported_var2(
&mut self,
name: E::VarName,
val: E::Var,
exported: Option<bool>,
env: &mut E
);
}
impl<'a, T, E: ?Sized> VarEnvRestorer2<E> for &'a mut T
where T: VarEnvRestorer2<E>,
E: VariableEnvironment,
{
fn set_exported_var2(
&mut self,
name: E::VarName,
val: E::Var,
exported: Option<bool>,
env: &mut E
) {
(**self).set_exported_var2(name, val, exported, env);
}
}
#[derive(Clone)]
pub struct VarRestorer<E: ?Sized>
where E: VariableEnvironment,
{
overrides: HashMap<E::VarName, Option<(E::Var, bool)>>,
}
impl<E: ?Sized> Eq for VarRestorer<E>
where E: VariableEnvironment,
E::VarName: Eq,
E::Var: Eq,
{}
impl<E: ?Sized> PartialEq<Self> for VarRestorer<E>
where E: VariableEnvironment,
E::VarName: Eq,
E::Var: Eq,
{
fn eq(&self, other: &Self) -> bool {
self.overrides == other.overrides
}
}
impl<E: ?Sized> fmt::Debug for VarRestorer<E>
where E: VariableEnvironment,
E::VarName: fmt::Debug,
E::Var: fmt::Debug,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("VarRestorer")
.field("overrides", &self.overrides)
.finish()
}
}
impl<E: ?Sized> Default for VarRestorer<E>
where E: VariableEnvironment,
{
fn default() -> Self {
Self::new()
}
}
impl<E: ?Sized> VarRestorer<E>
where E: VariableEnvironment,
{
pub fn new() -> Self {
VarRestorer {
overrides: HashMap::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
VarRestorer {
overrides: HashMap::with_capacity(capacity),
}
}
#[deprecated(note = "use the `VarEnvRestorer` trait instead")]
pub fn restore(mut self, env: &mut E)
where E: ExportedVariableEnvironment + UnsetVariableEnvironment,
{
self._restore(env);
}
fn _restore(&mut self, env: &mut E)
where E: ExportedVariableEnvironment + UnsetVariableEnvironment,
{
for (key, val) in self.overrides.drain() {
match val {
Some((val, exported)) => env.set_exported_var(key, val, exported),
None => env.unset_var(&key),
}
}
}
}
impl<E: ?Sized> VarRestorer<E>
where E: ExportedVariableEnvironment,
E::VarName: Clone,
E::Var: Clone,
{
#[deprecated(note = "use the `VarEnvRestorer` trait instead")]
pub fn set_exported_var(&mut self, name: E::VarName, val: E::Var, exported: bool, env: &mut E) {
self._set_exported_var(name, val, Some(exported), env);
}
fn _set_exported_var(
&mut self,
name: E::VarName,
val: E::Var,
exported: Option<bool>,
env: &mut E
) {
self._backup(name.clone(), env);
match exported {
Some(exported) => env.set_exported_var(name, val, exported),
None => env.set_var(name, val),
}
}
#[deprecated(note = "use the `VarEnvRestorer` trait instead")]
pub fn unset_var(&mut self, name: E::VarName, env: &mut E)
where E: UnsetVariableEnvironment,
{
VarEnvRestorer::unset_var(self, name, env)
}
#[deprecated(note = "use the `VarEnvRestorer` trait instead")]
pub fn backup(&mut self, key: E::VarName, env: &E) {
self._backup(key, env);
}
fn _backup(&mut self, key: E::VarName, env: &E) {
let value = env.exported_var(&key);
self.overrides.entry(key).or_insert_with(|| {
value.map(|(val, exported)| (val.clone(), exported))
});
}
}
impl<E: ?Sized> VarEnvRestorer<E> for VarRestorer<E>
where E: ExportedVariableEnvironment + UnsetVariableEnvironment,
E::VarName: Clone,
E::Var: Clone,
{
fn reserve(&mut self, additional: usize) {
self.overrides.reserve(additional);
}
fn set_exported_var(&mut self, name: E::VarName, val: E::Var, exported: bool, env: &mut E) {
self._set_exported_var(name, val, Some(exported), env);
}
fn unset_var(&mut self, name: E::VarName, env: &mut E) {
self._backup(name.clone(), env);
env.unset_var(&name);
}
fn backup(&mut self, key: E::VarName, env: &E) {
self._backup(key, env);
}
fn restore(&mut self, env: &mut E) {
self._restore(env);
}
}
impl<E: ?Sized> VarEnvRestorer2<E> for VarRestorer<E>
where E: ExportedVariableEnvironment + UnsetVariableEnvironment,
E::VarName: Clone,
E::Var: Clone,
{
fn set_exported_var2(
&mut self,
name: E::VarName,
val: E::Var,
exported: Option<bool>,
env: &mut E
) {
self._set_exported_var(name, val, exported, env);
}
}