use crate::{MaybeRwSignal, NoFilter};
use codee::CodecError;
use leptos::prelude::*;
use std::sync::Arc;
use thiserror::Error;
use wasm_bindgen::JsValue;
#[derive(Error, Debug)]
pub enum UseStorageError<E, D> {
#[error("storage not available")]
StorageNotAvailable(JsValue),
#[error("storage not returned from window")]
StorageReturnedNone,
#[error("failed to get item")]
GetItemFailed(JsValue),
#[error("failed to set item")]
SetItemFailed(JsValue),
#[error("failed to delete item")]
RemoveItemFailed(JsValue),
#[error("failed to notify item changed")]
NotifyItemChangedFailed(JsValue),
#[error("failed to encode / decode item value")]
ItemCodecError(CodecError<E, D>),
}
pub struct UseStorageOptions<T, E, D, F = NoFilter>
where
T: Send + Sync + 'static,
{
pub(crate) on_error: Arc<dyn Fn(UseStorageError<E, D>) + Send + Sync>,
pub(crate) listen_to_storage_changes: bool,
pub(crate) initial_value: MaybeRwSignal<T>,
pub(crate) filter: F,
pub(crate) delay_during_hydration: bool,
}
impl<T: Default, E, D> Default for UseStorageOptions<T, E, D>
where
T: Send + Sync + 'static,
{
fn default() -> Self {
Self {
on_error: Arc::new(|_err| ()),
listen_to_storage_changes: true,
initial_value: MaybeRwSignal::default(),
filter: NoFilter,
delay_during_hydration: false,
}
}
}
impl<T, E, D, F> UseStorageOptions<T, E, D, F>
where
T: Send + Sync + 'static,
{
pub fn on_error(
self,
on_error: impl Fn(UseStorageError<E, D>) + Send + Sync + 'static,
) -> Self {
Self {
on_error: Arc::new(on_error),
..self
}
}
pub fn listen_to_storage_changes(self, listen_to_storage_changes: bool) -> Self {
Self {
listen_to_storage_changes,
..self
}
}
pub fn initial_value(self, initial: impl Into<MaybeRwSignal<T>>) -> Self {
Self {
initial_value: initial.into(),
..self
}
}
pub fn filter<NewF>(self, filter: NewF) -> UseStorageOptions<T, E, D, NewF> {
UseStorageOptions {
on_error: self.on_error,
listen_to_storage_changes: self.listen_to_storage_changes,
initial_value: self.initial_value,
filter,
delay_during_hydration: self.delay_during_hydration,
}
}
pub fn delay_during_hydration(self, delay_during_hydration: bool) -> Self {
Self {
delay_during_hydration,
..self
}
}
}