use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Receiver, Sender};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ChangeType {
Css,
Script,
Html,
Other,
}
impl ChangeType {
pub fn from_path(path: &Path) -> Self {
match path.extension().and_then(|e| e.to_str()) {
Some("css") => ChangeType::Css,
Some("js" | "mjs") => ChangeType::Script,
Some("html" | "htm") => ChangeType::Html,
_ => ChangeType::Other,
}
}
pub fn as_str(&self) -> &'static str {
match self {
ChangeType::Css => "css",
ChangeType::Script => "script",
ChangeType::Html => "html",
ChangeType::Other => "other",
}
}
}
#[derive(Clone, Debug)]
pub struct ChangeEvent {
pub path: PathBuf,
pub change_type: ChangeType,
}
#[derive(Clone, Default)]
pub struct Broadcaster {
senders: Arc<Mutex<Vec<Sender<ChangeEvent>>>>,
}
impl Broadcaster {
pub fn new() -> Self {
Broadcaster::default()
}
pub fn broadcast(&self, event: ChangeEvent) {
let mut senders = self.senders.lock().unwrap();
senders.retain(|sender| sender.send(event.clone()).is_ok());
}
pub fn subscribe(&self) -> Receiver<ChangeEvent> {
let (tx, rx) = channel();
self.senders.lock().unwrap().push(tx);
rx
}
#[cfg(test)]
pub fn subscriber_count(&self) -> usize {
self.senders.lock().unwrap().len()
}
}
#[cfg(test)]
#[path = "../tests/unit/change.rs"]
mod tests;