Skip to main content

CommonLibrary/FileSystem/
FileWatcherProvider.rs

1//! # FileWatcherProvider Trait
2//!
3//! Defines the abstract contract for a service that registers recursive
4//! filesystem watchers backed by the host platform's native notification
5//! mechanism (inotify / FSEvents / ReadDirectoryChangesW). Watch events are
6//! streamed back to the extension host as `$fileWatcher:event` notifications
7//! so language features, TS watch-mode, HMR, and prettier-on-save all keep
8//! working without polling.
9
10use std::path::PathBuf;
11
12use async_trait::async_trait;
13
14use crate::{Environment::Environment::Environment, Error::CommonError::CommonError};
15
16/// The kind of event a watcher observed.
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum WatchEventKind {
19	Create,
20	Change,
21	Delete,
22}
23
24impl WatchEventKind {
25	pub fn AsString(&self) -> &'static str {
26		match self {
27			WatchEventKind::Create => "create",
28			WatchEventKind::Change => "change",
29			WatchEventKind::Delete => "delete",
30		}
31	}
32}
33
34/// A single watch event emitted from the underlying notifier.
35#[derive(Debug, Clone)]
36pub struct WatchEvent {
37	pub Handle:String,
38	pub Kind:WatchEventKind,
39	pub Path:PathBuf,
40}
41
42/// An abstract service contract for registering and cancelling recursive
43/// filesystem watchers.
44#[async_trait]
45pub trait FileWatcherProvider: Environment + Send + Sync {
46	/// Register a new watcher. `Handle` is a caller-supplied identifier
47	/// (e.g. `"watcher:7"`) that must be echoed back in every emitted event so
48	/// the extension host can route events to the right subscriber.
49	///
50	/// # Parameters
51	/// * `Handle`:      Caller-supplied watcher identifier.
52	/// * `Root`:        Absolute path of the directory to watch.
53	/// * `IsRecursive`: When `true`, observe children recursively.
54	/// * `Pattern`:     Optional glob pattern (e.g. `**/*.ts`). When present,
55	///                  events whose path does not match the compiled pattern
56	///                  are dropped before crossing the IPC boundary - this
57	///                  is critical for performance under TypeScript-style
58	///                  extensions that register 10+ watchers per activation.
59	async fn RegisterWatcher(
60		&self,
61		Handle:String,
62		Root:PathBuf,
63		IsRecursive:bool,
64		Pattern:Option<String>,
65	) -> Result<(), CommonError>;
66
67	/// Cancel a watcher registered with `RegisterWatcher`. Unknown handles
68	/// resolve to `Ok(())` so callers may safely call `dispose()` without
69	/// tracking registration state.
70	async fn UnregisterWatcher(&self, Handle:String) -> Result<(), CommonError>;
71}