turbo_tasks_fs/
invalidation.rs

1use std::{
2    any::Any,
3    fmt::{Display, Formatter},
4    hash::Hash,
5};
6
7use turbo_rcstr::RcStr;
8use turbo_tasks::{FxIndexSet, InvalidationReason, InvalidationReasonKind, util::StaticOrArc};
9
10/// Invalidation was caused by a file change detected by the file watcher
11#[derive(PartialEq, Eq, Hash)]
12pub(crate) struct WatchChange {
13    pub path: String,
14}
15
16impl InvalidationReason for WatchChange {
17    fn kind(&self) -> Option<StaticOrArc<dyn InvalidationReasonKind>> {
18        Some(StaticOrArc::Static(&WATCH_CHANGE_KIND))
19    }
20}
21
22impl Display for WatchChange {
23    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
24        write!(f, "{} changed", self.path)
25    }
26}
27
28/// Invalidation kind for [WatchChange]
29#[derive(PartialEq, Eq, Hash)]
30struct WatchChangeKind;
31
32static WATCH_CHANGE_KIND: WatchChangeKind = WatchChangeKind;
33
34impl InvalidationReasonKind for WatchChangeKind {
35    fn fmt(
36        &self,
37        reasons: &FxIndexSet<StaticOrArc<dyn InvalidationReason>>,
38        f: &mut Formatter<'_>,
39    ) -> std::fmt::Result {
40        let first_reason: &dyn InvalidationReason = &*reasons[0];
41        write!(
42            f,
43            "{} files changed ({}, ...)",
44            reasons.len(),
45            (first_reason as &dyn Any)
46                .downcast_ref::<WatchChange>()
47                .unwrap()
48                .path
49        )
50    }
51}
52
53/// Invalidation was caused by a directory starting to watch from which was read
54/// before.
55#[derive(PartialEq, Eq, Hash, Clone)]
56pub(crate) struct WatchStart {
57    pub name: RcStr,
58    pub path: RcStr,
59}
60
61impl InvalidationReason for WatchStart {
62    fn kind(&self) -> Option<StaticOrArc<dyn InvalidationReasonKind>> {
63        Some(StaticOrArc::Static(&WATCH_START_KIND))
64    }
65}
66
67impl Display for WatchStart {
68    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
69        write!(f, "started watching {} in {}", self.path, self.name)
70    }
71}
72
73/// Invalidation kind for [WatchStart]
74#[derive(PartialEq, Eq, Hash)]
75struct WatchStartKind;
76
77static WATCH_START_KIND: WatchStartKind = WatchStartKind;
78
79impl InvalidationReasonKind for WatchStartKind {
80    fn fmt(
81        &self,
82        reasons: &FxIndexSet<StaticOrArc<dyn InvalidationReason>>,
83        f: &mut Formatter<'_>,
84    ) -> std::fmt::Result {
85        let first_reason: &dyn InvalidationReason = &*reasons[0];
86        let example = (first_reason as &dyn Any)
87            .downcast_ref::<WatchStart>()
88            .unwrap();
89        write!(
90            f,
91            "{} items started watching (e.g. {} in {})",
92            reasons.len(),
93            example.path,
94            example.name
95        )
96    }
97}
98
99/// Invalidation was caused by initialization of a project or filesystem.
100#[derive(PartialEq, Eq, Hash, Clone)]
101pub struct Initialize {
102    pub path: RcStr,
103}
104
105impl InvalidationReason for Initialize {
106    fn kind(&self) -> Option<StaticOrArc<dyn InvalidationReasonKind>> {
107        Some(StaticOrArc::Static(&INITIALIZE_KIND))
108    }
109}
110
111impl Display for Initialize {
112    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
113        write!(
114            f,
115            "initialized project or filesystem with path {}",
116            self.path
117        )
118    }
119}
120
121/// [Invalidation kind][InvalidationReasonKind] for [`Initialize`].
122#[derive(PartialEq, Eq, Hash)]
123struct InitializeKind;
124
125static INITIALIZE_KIND: InitializeKind = InitializeKind;
126
127impl InvalidationReasonKind for InitializeKind {
128    fn fmt(
129        &self,
130        reasons: &FxIndexSet<StaticOrArc<dyn InvalidationReason>>,
131        f: &mut Formatter<'_>,
132    ) -> std::fmt::Result {
133        let first_reason: &dyn InvalidationReason = &*reasons[0];
134        let example = (first_reason as &dyn Any)
135            .downcast_ref::<Initialize>()
136            .unwrap();
137        write!(
138            f,
139            "{} items invalidated as part of project or filesystem initialization ({}, ...)",
140            reasons.len(),
141            example.path,
142        )
143    }
144}
145
146/// Invalidation was caused by a write operation on the filesystem
147#[derive(PartialEq, Eq, Hash)]
148pub(crate) struct Write {
149    pub path: String,
150}
151
152impl InvalidationReason for Write {
153    fn kind(&self) -> Option<StaticOrArc<dyn InvalidationReasonKind>> {
154        Some(StaticOrArc::Static(&WRITE_KIND))
155    }
156}
157
158impl Display for Write {
159    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
160        write!(f, "{} written", self.path)
161    }
162}
163
164/// Invalidation kind for [Write]
165#[derive(PartialEq, Eq, Hash)]
166struct WriteKind;
167
168static WRITE_KIND: WriteKind = WriteKind;
169
170impl InvalidationReasonKind for WriteKind {
171    fn fmt(
172        &self,
173        reasons: &FxIndexSet<StaticOrArc<dyn InvalidationReason>>,
174        f: &mut Formatter<'_>,
175    ) -> std::fmt::Result {
176        let first_reason: &dyn InvalidationReason = &*reasons[0];
177        write!(
178            f,
179            "{} files written ({}, ...)",
180            reasons.len(),
181            (first_reason as &dyn Any)
182                .downcast_ref::<Write>()
183                .unwrap()
184                .path
185        )
186    }
187}