Skip to content

Instantly share code, notes, and snippets.

@justinwoo
Created February 28, 2020 10:42
Show Gist options
  • Save justinwoo/dd1d05c1a4bfd7a38e4d4d1031f11280 to your computer and use it in GitHub Desktop.
Save justinwoo/dd1d05c1a4bfd7a38e4d4d1031f11280 to your computer and use it in GitHub Desktop.
How would I avoid having to manually wrap the inner observable methods each time I use this?
// this is a parameterized Observable i would like to expose concretely typed versions of
pub struct Observable<A> {
pub state: A,
observers: Vec<js_sys::Function>,
}
// these are the methods I'd like to expose out of here
// i would especially like to expose new, subscribe, unsubscribe
impl<A: Serialize> Observable<A> {
pub fn new(state: A) -> Self {
Observable {
state,
observers: vec![],
}
}
fn emit(&self) {
let js_value = JsValue::from_serde(&self.state).unwrap();
for observer in self.observers.iter() {
let _ = observer.call1(&JsValue::null(), &js_value);
}
}
pub fn subscribe(&mut self, callback: js_sys::Function) {
self.observers.push(callback);
}
pub fn unsubscribe(&mut self, callback: js_sys::Function) {
self.observers.remove_item(&callback);
}
pub fn update<F: Fn(&A) -> A>(&mut self, update: F) {
self.state = update(&self.state);
self.emit();
}
}
// this is my exposed struct
#[wasm_bindgen]
pub struct Counter {
observable: Observable<u32>,
}
#[wasm_bindgen]
impl Counter {
pub fn new() -> Self {
Counter {
observable: Observable::new(0),
}
}
pub fn tick(&mut self) {
self.observable.update(|state| state + 1)
}
// i would like to avoid having to crap these calls to subscribe and unsubscribe,
// but don't see how i would be able to
pub fn subscribe(&mut self, callback: js_sys::Function) {
self.observable.subscribe(callback);
}
pub fn unsubscribe(&mut self, callback: js_sys::Function) {
self.observable.subscribe(callback);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment