use crate::manager::FileManager;
use std::ops::{Deref, DerefMut};
use std::path::Path;
pub type StandardContainer<T, Format> = Container<T, crate::manager::standard::StandardManager<Format>>;
pub type StandardContainerOptions = crate::manager::standard::StandardManagerOptions;
#[cfg_attr(docsrs, doc(cfg(feature = "atomic")))]
#[cfg(feature = "atomic")]
pub type AtomicContainer<T, Format, Support> = Container<T, crate::manager::atomic::AtomicManager<Format, Support>>;
#[cfg_attr(docsrs, doc(cfg(feature = "atomic")))]
#[cfg(feature = "atomic")]
pub type AtomicContainerOptions<Support> = crate::manager::atomic::AtomicManagerOptions<Support>;
#[derive(Debug)]
pub struct Container<T, Manager> {
pub(crate) value: T,
pub(crate) manager: Manager
}
impl<T, Manager> Container<T, Manager> {
#[inline(always)]
pub const fn new(value: T, manager: Manager) -> Self {
Container { value, manager }
}
#[inline(always)]
pub fn into_value(self) -> T {
self.value
}
#[inline(always)]
pub fn into_manager(self) -> Manager {
self.manager
}
#[inline(always)]
pub const fn manager(&self) -> &Manager {
&self.manager
}
#[inline(always)]
pub const fn manager_mut(&mut self) -> &mut Manager {
&mut self.manager
}
#[inline(always)]
pub const fn get(&self) -> &T {
&self.value
}
#[inline(always)]
pub const fn get_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<T, Manager> Container<T, Manager>
where Manager: FileManager<T> {
pub fn open<P: AsRef<Path>>(
path: P, format: Manager::Format, options: Manager::Options
) -> Result<Self, Manager::Error> {
let mut manager = Manager::open(path, format, options)?;
let value = manager.read()?;
Ok(Container { value, manager })
}
pub fn create_overwrite<P: AsRef<Path>>(
path: P, format: Manager::Format, options: Manager::Options, value: T
) -> Result<Self, Manager::Error> {
let (value, manager) = Manager::create_overwrite(path, format, options, value)?;
Ok(Container { value, manager })
}
pub fn create_or<P: AsRef<Path>>(
path: P, format: Manager::Format, options: Manager::Options, value: T
) -> Result<Self, Manager::Error> {
let (value, manager) = Manager::create_or(path, format, options, value)?;
Ok(Container { value, manager })
}
pub fn create_or_else<P: AsRef<Path>, C>(
path: P, format: Manager::Format, options: Manager::Options, closure: C
) -> Result<Self, Manager::Error>
where C: FnOnce() -> T {
let (value, manager) = Manager::create_or_else(path, format, options, closure)?;
Ok(Container { value, manager })
}
pub fn create_or_default<P: AsRef<Path>>(
path: P, format: Manager::Format, options: Manager::Options
) -> Result<Self, Manager::Error>
where T: Default {
let (value, manager) = Manager::create_or_default(path, format, options)?;
Ok(Container { value, manager })
}
#[doc(alias = "load", alias = "reload")]
pub fn refresh(&mut self) -> Result<T, Manager::Error> {
self.manager.read().map(|value| std::mem::replace(&mut self.value, value))
}
#[doc(alias = "store", alias = "save")]
pub fn commit(&mut self) -> Result<(), Manager::Error> {
self.manager.write(&self.value)
}
#[doc(alias = "replace")]
pub fn overwrite(&mut self, value: T) -> Result<(), Manager::Error> {
self.value = value;
self.manager.write(&self.value)
}
pub fn close(self) -> Result<T, Manager::Error> {
self.manager.close().map(|()| self.value)
}
}
impl<T, Manager> Deref for Container<T, Manager> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.get()
}
}
impl<T, Manager> DerefMut for Container<T, Manager> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
self.get_mut()
}
}