turbopack_core/
condition.rs1use serde::{Deserialize, Serialize};
2use turbo_tasks::{NonLocalValue, trace::TraceRawVcs};
3use turbo_tasks_fs::FileSystemPath;
4
5#[derive(Debug, Clone, Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, NonLocalValue)]
6pub enum ContextCondition {
7 All(Vec<ContextCondition>),
8 Any(Vec<ContextCondition>),
9 Not(Box<ContextCondition>),
10 InDirectory(String),
11 InPath(FileSystemPath),
12}
13
14impl ContextCondition {
15 pub fn all(conditions: Vec<ContextCondition>) -> ContextCondition {
17 ContextCondition::All(conditions)
18 }
19
20 pub fn any(conditions: Vec<ContextCondition>) -> ContextCondition {
22 ContextCondition::Any(conditions)
23 }
24
25 #[allow(clippy::should_implement_trait)]
27 pub fn not(condition: ContextCondition) -> ContextCondition {
28 ContextCondition::Not(Box::new(condition))
29 }
30
31 pub fn matches(&self, path: &FileSystemPath) -> bool {
33 match self {
34 ContextCondition::All(conditions) => conditions.iter().all(|c| c.matches(path)),
35 ContextCondition::Any(conditions) => conditions.iter().any(|c| c.matches(path)),
36 ContextCondition::Not(condition) => !condition.matches(path),
37 ContextCondition::InPath(other_path) => path.is_inside_or_equal_ref(other_path),
38 ContextCondition::InDirectory(dir) => {
39 if let Some(pos) = path.path.find(dir) {
41 let end = pos + dir.len();
42 (pos == 0 || path.path.as_bytes()[pos - 1] == b'/')
43 && (end == path.path.len() || path.path.as_bytes()[end] == b'/')
44 } else {
45 false
46 }
47 }
48 }
49 }
50}