use std::rc::Rc;
use crate::{
computed::{Client, Value, DropResource, context::Context},
struct_mut::ValueMut, get_driver, Computed,
};
struct HashSubscriptions {
_sender: Client,
_receiver: DropResource,
}
#[derive(Clone)]
pub struct HashRouter<T: Clone + ToString + From<String> + PartialEq + 'static> {
route_value: Value<T>,
pub route: Computed<T>,
_subscriptions: Rc<HashSubscriptions>,
}
impl<T: Clone + ToString + From<String> + PartialEq + 'static> PartialEq for HashRouter<T> {
fn eq(&self, other: &Self) -> bool {
self.route_value.id() == other.route_value.id()
}
}
impl<T: Clone + ToString + From<String> + PartialEq + 'static> HashRouter<T> {
#[allow(clippy::new_without_default)]
pub fn new() -> Self {
let driver = get_driver();
let route_value: Value<T> = Value::new(T::from(driver.get_hash_location()));
let block_subscrition = Rc::new(ValueMut::new(true));
let sender = route_value.to_computed().subscribe({
let driver = driver.clone();
let block_subscrition = block_subscrition.clone();
move |route| {
if block_subscrition.get() {
return;
}
driver.push_hash_location(route.to_string());
}
});
let receiver = driver.on_hash_route_change({
let route = route_value.clone();
let block_subscrition = block_subscrition.clone();
Box::new(move |url: String| {
block_subscrition.set(true);
route.set_value_and_compare(T::from(url));
block_subscrition.set(false);
})
});
block_subscrition.set(false);
let route = route_value.to_computed();
Self {
route_value,
route,
_subscriptions: Rc::new(HashSubscriptions {
_sender: sender,
_receiver: receiver
})
}
}
pub fn set(&self, value: T) {
self.route_value.set_value_and_compare(value);
}
pub fn get(&self, context: &Context) -> T {
self.route_value.get(context)
}
}