librespot_core/dealer/
maps.rs1use std::collections::HashMap;
2
3use crate::Error;
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7pub enum HandlerMapError {
8 #[error("request was already handled")]
9 AlreadyHandled,
10}
11
12impl From<HandlerMapError> for Error {
13 fn from(err: HandlerMapError) -> Self {
14 Error::aborted(err)
15 }
16}
17
18pub enum HandlerMap<T> {
19 Leaf(T),
20 Branch(HashMap<String, HandlerMap<T>>),
21}
22
23impl<T> Default for HandlerMap<T> {
24 fn default() -> Self {
25 Self::Branch(HashMap::new())
26 }
27}
28
29impl<T> HandlerMap<T> {
30 pub fn contains(&self, path: &str) -> bool {
31 matches!(self, HandlerMap::Branch(map) if map.contains_key(path))
32 }
33
34 pub fn insert<'a>(
35 &mut self,
36 mut path: impl Iterator<Item = &'a str>,
37 handler: T,
38 ) -> Result<(), Error> {
39 match self {
40 Self::Leaf(_) => Err(HandlerMapError::AlreadyHandled.into()),
41 Self::Branch(children) => {
42 if let Some(component) = path.next() {
43 let node = children.entry(component.to_owned()).or_default();
44 node.insert(path, handler)
45 } else if children.is_empty() {
46 *self = Self::Leaf(handler);
47 Ok(())
48 } else {
49 Err(HandlerMapError::AlreadyHandled.into())
50 }
51 }
52 }
53 }
54
55 pub fn get<'a>(&self, mut path: impl Iterator<Item = &'a str>) -> Option<&T> {
56 match self {
57 Self::Leaf(t) => Some(t),
58 Self::Branch(m) => {
59 let component = path.next()?;
60 m.get(component)?.get(path)
61 }
62 }
63 }
64
65 pub fn remove<'a>(&mut self, mut path: impl Iterator<Item = &'a str>) -> Option<T> {
66 match self {
67 Self::Leaf(_) => match std::mem::take(self) {
68 Self::Leaf(t) => Some(t),
69 _ => unreachable!(),
70 },
71 Self::Branch(map) => {
72 let component = path.next()?;
73 let next = map.get_mut(component)?;
74 let result = next.remove(path);
75 match &*next {
76 Self::Branch(b) if b.is_empty() => {
77 map.remove(component);
78 }
79 _ => (),
80 }
81 result
82 }
83 }
84 }
85}
86
87pub struct SubscriberMap<T> {
88 subscribed: Vec<T>,
89 children: HashMap<String, SubscriberMap<T>>,
90}
91
92impl<T> Default for SubscriberMap<T> {
93 fn default() -> Self {
94 Self {
95 subscribed: Vec::new(),
96 children: HashMap::new(),
97 }
98 }
99}
100
101impl<T> SubscriberMap<T> {
102 pub fn insert<'a>(&mut self, mut path: impl Iterator<Item = &'a str>, handler: T) {
103 if let Some(component) = path.next() {
104 self.children
105 .entry(component.to_owned())
106 .or_default()
107 .insert(path, handler);
108 } else {
109 self.subscribed.push(handler);
110 }
111 }
112
113 pub fn contains<'a>(&self, mut path: impl Iterator<Item = &'a str>) -> bool {
114 if !self.subscribed.is_empty() {
115 return true;
116 }
117
118 if let Some(next) = path.next() {
119 if let Some(next_map) = self.children.get(next) {
120 return next_map.contains(path);
121 }
122 } else {
123 return !self.is_empty();
124 }
125
126 false
127 }
128
129 pub fn is_empty(&self) -> bool {
130 self.children.is_empty() && self.subscribed.is_empty()
131 }
132
133 pub fn retain<'a>(
134 &mut self,
135 mut path: impl Iterator<Item = &'a str>,
136 fun: &mut impl FnMut(&T) -> bool,
137 ) -> bool {
138 let mut handled_by_any = false;
139 self.subscribed.retain(|x| {
140 handled_by_any = true;
141 fun(x)
142 });
143
144 if let Some(next) = path.next() {
145 if let Some(y) = self.children.get_mut(next) {
146 handled_by_any = handled_by_any || y.retain(path, fun);
147 if y.is_empty() {
148 self.children.remove(next);
149 }
150 }
151 }
152
153 handled_by_any
154 }
155}