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}