Skip to main content

substrate_core/
watcher_port.rs

1//! WatcherPort — debounced filesystem watch events.
2//!
3//! Core defines the port contract; `file-watcher` wraps the `notify` crate
4//! (inotify / FSEvents / ReadDirectoryChangesW) with a debounced stream.
5
6use std::path::{Path, PathBuf};
7use std::time::Duration;
8
9use async_trait::async_trait;
10use serde::{Deserialize, Serialize};
11use uuid::Uuid;
12
13use crate::error::Result;
14
15/// Kind of filesystem change observed by a watcher.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
17pub enum WatchEventKind {
18    /// A path was created.
19    Create,
20    /// A path was modified.
21    Modify,
22    /// A path was removed.
23    Remove,
24    /// Any other/normalized event kind.
25    Other,
26}
27
28/// A single debounced watch notification.
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
30pub struct WatchEvent {
31    /// Affected path.
32    pub path: PathBuf,
33    /// Normalized event kind.
34    pub kind: WatchEventKind,
35}
36
37/// Subscription handle returned by [`WatcherPort::watch`].
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
39pub struct WatchHandle {
40    /// Adapter-local subscription id.
41    pub id: Uuid,
42}
43
44/// Filesystem watch port with debounced event delivery.
45#[async_trait]
46pub trait WatcherPort: Send + Sync {
47    /// Begin watching `path` (non-recursive) with `debounce_ms` coalescing.
48    async fn watch(&self, path: &Path, debounce_ms: u64) -> Result<WatchHandle>;
49
50    /// Receive the next debounced event, waiting up to `timeout`.
51    async fn recv_event(
52        &self,
53        handle: &WatchHandle,
54        timeout: Duration,
55    ) -> Result<Option<WatchEvent>>;
56
57    /// Stop watching and release resources for `handle`.
58    async fn unwatch(&self, handle: &WatchHandle) -> Result<()>;
59}