subscription.rs

 1use crate::{Edit, Patch};
 2use parking_lot::Mutex;
 3use std::{
 4    mem,
 5    sync::{Arc, Weak},
 6};
 7
 8#[derive(Default)]
 9pub struct Topic(Mutex<Vec<Weak<Mutex<Patch<usize>>>>>);
10
11pub struct Subscription(Arc<Mutex<Patch<usize>>>);
12
13impl Topic {
14    pub fn subscribe(&mut self) -> Subscription {
15        let subscription = Subscription(Default::default());
16        self.0.get_mut().push(Arc::downgrade(&subscription.0));
17        subscription
18    }
19
20    pub fn publish(&self, edits: impl Clone + IntoIterator<Item = Edit<usize>>) {
21        publish(&mut self.0.lock(), edits);
22    }
23
24    pub fn publish_mut(&mut self, edits: impl Clone + IntoIterator<Item = Edit<usize>>) {
25        publish(self.0.get_mut(), edits);
26    }
27}
28
29impl Subscription {
30    pub fn consume(&self) -> Patch<usize> {
31        mem::take(&mut *self.0.lock())
32    }
33}
34
35fn publish(
36    subscriptions: &mut Vec<Weak<Mutex<Patch<usize>>>>,
37    edits: impl Clone + IntoIterator<Item = Edit<usize>>,
38) {
39    subscriptions.retain(|subscription| {
40        if let Some(subscription) = subscription.upgrade() {
41            let mut patch = subscription.lock();
42            *patch = patch.compose(edits.clone());
43            true
44        } else {
45            false
46        }
47    });
48}