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}