turbo_tasks_env/
filter.rs

1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{FxIndexMap, ResolvedVc, Vc};
4
5use crate::{EnvMap, ProcessEnv};
6
7/// Filters env variables by some prefix. Casing of the env vars is ignored for
8/// filtering.
9#[turbo_tasks::value]
10pub struct FilterProcessEnv {
11    prior: ResolvedVc<Box<dyn ProcessEnv>>,
12    filters: Vec<RcStr>,
13}
14
15#[turbo_tasks::value_impl]
16impl FilterProcessEnv {
17    #[turbo_tasks::function]
18    pub fn new(prior: ResolvedVc<Box<dyn ProcessEnv>>, filters: Vec<RcStr>) -> Vc<Self> {
19        FilterProcessEnv {
20            prior,
21            filters: filters
22                .into_iter()
23                .map(|f| f.to_uppercase().into())
24                .collect(),
25        }
26        .cell()
27    }
28}
29
30#[turbo_tasks::value_impl]
31impl ProcessEnv for FilterProcessEnv {
32    #[turbo_tasks::function]
33    async fn read_all(&self) -> Result<Vc<EnvMap>> {
34        let prior = self.prior.read_all().await?;
35        let mut filtered = FxIndexMap::default();
36        for (key, value) in &*prior {
37            let uppercase = key.to_uppercase();
38            for filter in &self.filters {
39                if uppercase.starts_with(&**filter) {
40                    filtered.insert(key.clone(), value.clone());
41                    break;
42                }
43            }
44        }
45        Ok(Vc::cell(filtered))
46    }
47
48    #[turbo_tasks::function]
49    fn read(&self, name: RcStr) -> Vc<Option<RcStr>> {
50        for filter in &self.filters {
51            if name.to_uppercase().starts_with(&**filter) {
52                return self.prior.read(name);
53            }
54        }
55        Vc::cell(None)
56    }
57}