coven_foundation/files/
reached.rs1use crate::locks::lock_unpoisoned;
8use std::path::{Path, PathBuf};
9use std::sync::Mutex;
10
11type Watch = (PathBuf, tokio::sync::oneshot::Sender<()>);
12
13static WATCHED: Mutex<Vec<Watch>> = Mutex::new(Vec::new());
14
15pub fn when_reached(path: &Path) -> tokio::sync::oneshot::Receiver<()> {
18 let (told, telling) = tokio::sync::oneshot::channel();
19 lock_unpoisoned(&WATCHED).push((resolved(path), told));
20 telling
21}
22
23pub(super) fn reached(path: &Path) {
25 let path = resolved(path);
26 let mut watched = lock_unpoisoned(&WATCHED);
27 let (found, rest): (Vec<Watch>, Vec<Watch>) =
28 std::mem::take(&mut *watched).into_iter().partition(|(watched, _)| *watched == path);
29 *watched = rest;
30 for (_, told) in found {
31 #[expect(
32 clippy::let_underscore_must_use,
33 reason = "a test that stopped listening has no use for it"
34 )]
35 let _ = told.send(());
36 }
37}
38
39fn resolved(path: &Path) -> PathBuf {
42 match (path.parent().and_then(|parent| std::fs::canonicalize(parent).ok()), path.file_name()) {
43 (Some(parent), Some(name)) => parent.join(name),
44 _ => path.to_owned(),
45 }
46}