use crate::prelude::*;
pub struct PersistentBuilder<R: Resource + Serialize + DeserializeOwned> {
pub(crate) name: Option<String>,
pub(crate) format: Option<StorageFormat>,
pub(crate) path: Option<PathBuf>,
pub(crate) default: Option<R>,
}
impl<R: Resource + Serialize + DeserializeOwned> PersistentBuilder<R> {
pub fn name(mut self, name: impl ToString) -> PersistentBuilder<R> {
self.name = Some(name.to_string());
self
}
pub fn format(mut self, format: StorageFormat) -> PersistentBuilder<R> {
self.format = Some(format);
self
}
pub fn path(mut self, path: impl Into<PathBuf>) -> PersistentBuilder<R> {
self.path = Some(path.into());
self
}
pub fn default(mut self, resource: R) -> PersistentBuilder<R> {
self.default = Some(resource);
self
}
}
impl<R: Resource + Serialize + DeserializeOwned> PersistentBuilder<R> {
pub fn build(self) -> Persistent<R> {
if self.name.is_none() {
panic!("persistent resource name is not set");
}
if self.format.is_none() {
panic!("persistent resource format is not set");
}
if self.path.is_none() {
panic!("persistent resource path is not set");
}
if self.default.is_none() {
panic!("persistent resource default is not set");
}
let name = self.name.unwrap();
let format = self.format.unwrap();
let path = self.path.unwrap();
let default = self.default.unwrap();
let storage = {
#[cfg(not(target_family = "wasm"))]
{
Storage::Filesystem { path: path.canonicalize().unwrap_or(path) }
}
#[cfg(target_family = "wasm")]
{
let separator = std::path::MAIN_SEPARATOR_STR;
let path = path.strip_prefix(separator).unwrap_or(&path);
if let Ok(Some(key)) = path.strip_prefix("local").map(|p| p.to_str()) {
Storage::LocalStorage { key: key.to_owned() }
} else if let Ok(Some(key)) = path.strip_prefix("session").map(|p| p.to_str()) {
Storage::SessionStorage { key: key.to_owned() }
} else {
panic!(
"persistent resource path should start with \
\"local\" or \"session\" and be UTF-8 encoded in WebAssembly",
);
}
}
};
Persistent::new(name, format, storage, default)
}
}