taplo_common/
environment.rs

1use async_trait::async_trait;
2use futures::Future;
3use std::path::{Path, PathBuf};
4use time::OffsetDateTime;
5use tokio::io::{AsyncRead, AsyncWrite};
6use url::Url;
7
8use crate::util::Normalize;
9
10#[cfg(not(target_family = "wasm"))]
11pub mod native;
12
13/// An environment in which the operations with Taplo are executed.
14///
15/// This is mostly needed for sandboxed environments such as WebAssembly.
16#[async_trait(?Send)]
17pub trait Environment: Clone + Send + Sync + 'static {
18    type Stdin: AsyncRead + Unpin;
19    type Stdout: AsyncWrite + Unpin;
20    type Stderr: AsyncWrite + Unpin;
21
22    fn now(&self) -> OffsetDateTime;
23
24    fn spawn<F>(&self, fut: F)
25    where
26        F: Future + Send + 'static,
27        F::Output: Send;
28
29    fn spawn_local<F>(&self, fut: F)
30    where
31        F: Future + 'static;
32
33    fn env_var(&self, name: &str) -> Option<String>;
34
35    fn env_vars(&self) -> Vec<(String, String)>;
36
37    fn atty_stderr(&self) -> bool;
38    fn stdin(&self) -> Self::Stdin;
39    fn stdout(&self) -> Self::Stdout;
40    fn stderr(&self) -> Self::Stderr;
41
42    fn glob_files(&self, glob: &str) -> Result<Vec<PathBuf>, anyhow::Error>;
43
44    async fn read_file(&self, path: &Path) -> Result<Vec<u8>, anyhow::Error>;
45
46    async fn write_file(&self, path: &Path, bytes: &[u8]) -> Result<(), anyhow::Error>;
47
48    fn to_file_path(&self, url: &Url) -> Option<PathBuf>;
49
50    fn is_absolute(&self, path: &Path) -> bool;
51
52    /// Absolute current working dir.
53    fn cwd(&self) -> Option<PathBuf>;
54
55    async fn find_config_file(&self, from: &Path) -> Option<PathBuf>;
56
57    /// Same as [`Self::glob_files`], but the returned paths are
58    /// [normalized](Normalize:normalize) in addition.
59    fn glob_files_normalized(&self, glob: &str) -> Result<Vec<PathBuf>, anyhow::Error> {
60        Ok(self
61            .glob_files(glob)?
62            .into_iter()
63            .map(Normalize::normalize)
64            .collect())
65    }
66
67    /// Same as [`Self::cwd`], but the returned path is
68    /// [normalized](Normalize:normalize) in addition.
69    fn cwd_normalized(&self) -> Option<PathBuf> {
70        self.cwd().map(Normalize::normalize)
71    }
72
73    /// Same as [`Self::to_file_path`], but the returned path is
74    /// [normalized](Normalize:normalize) in addition.
75    fn to_file_path_normalized(&self, url: &Url) -> Option<PathBuf> {
76        self.to_file_path(url).map(Normalize::normalize)
77    }
78
79    /// Same as [`Self::find_config_file`], but the returned path is
80    /// [normalized](Normalize:normalize) in addition.
81    async fn find_config_file_normalized(&self, from: &Path) -> Option<PathBuf> {
82        self.find_config_file(from).await.map(Normalize::normalize)
83    }
84}