use std::{
collections::HashMap,
sync::{Mutex, MutexGuard, PoisonError},
};
use super::{Directions, RawSource};
pub(super) struct List {
inner: Mutex<Listed>,
}
impl List {
pub(super) fn new() -> Self {
Self {
inner: Mutex::new(Listed {
watched: HashMap::new(),
added: 0,
}),
}
}
pub(super) fn add(&self) -> usize {
let mut listed = self.lock();
listed.added += 1;
listed.added
}
pub(super) fn modify(&self, key: usize, descriptor: RawSource, to: Directions) {
let mut listed = self.lock();
if to.is_empty() {
listed.watched.remove(&key);
} else {
listed.watched.insert(key, (descriptor, to));
}
}
pub(super) fn delete(&self, key: usize) {
let mut listed = self.lock();
listed.watched.remove(&key);
listed.added -= 1;
}
pub(super) fn snapshot(&self) -> Vec<(usize, RawSource, Directions)> {
self.lock()
.watched
.iter()
.map(|(&key, &(descriptor, directions))| (key, descriptor, directions))
.collect()
}
fn lock(&self) -> MutexGuard<'_, Listed> {
self.inner.lock().unwrap_or_else(PoisonError::into_inner)
}
}
struct Listed {
watched: HashMap<usize, (RawSource, Directions)>,
added: usize,
}