Skip to main content

dvm_run/
files.rs

1//! Files in a sandbox, written in and read out whole.
2
3use reqwest::Method;
4
5use crate::error::{Error, Result};
6use crate::sandbox::SandboxCalls;
7
8/// A sandbox's files: [`Sandbox::files`](crate::Sandbox::files).
9pub struct Files {
10    calls: SandboxCalls,
11}
12
13impl Files {
14    pub(crate) fn new(calls: SandboxCalls) -> Self {
15        Self { calls }
16    }
17
18    /// Writes `data` to the file at `path`, in place of what it held; a new
19    /// file gets mode `0o644`.
20    pub async fn write(&self, path: &str, data: impl Into<Vec<u8>>) -> Result<()> {
21        self.put(path, data.into(), None).await
22    }
23
24    /// Writes `data` to the file at `path`, and a new file gets `mode`
25    /// (`0o755`).
26    pub async fn write_with_mode(
27        &self,
28        path: &str,
29        data: impl Into<Vec<u8>>,
30        mode: u32,
31    ) -> Result<()> {
32        self.put(path, data.into(), Some(mode)).await
33    }
34
35    /// The file at `path`, as it is.
36    pub async fn read(&self, path: &str) -> Result<Vec<u8>> {
37        let calls = &self.calls;
38        let query = [("path", path.to_owned())];
39        let files = format!("{}/files", calls.path);
40        calls
41            .while_live(calls.client.bytes(Method::GET, &files, &query, None))
42            .await
43    }
44
45    /// The file at `path`, as UTF-8 text.
46    pub async fn read_text(&self, path: &str) -> Result<String> {
47        String::from_utf8(self.read(path).await?)
48            .map_err(|_| Error::Unexpected(format!("{path} isn't UTF-8")))
49    }
50
51    async fn put(&self, path: &str, data: Vec<u8>, mode: Option<u32>) -> Result<()> {
52        let calls = &self.calls;
53        let mut query = vec![("path", path.to_owned())];
54        if let Some(mode) = mode {
55            query.push(("mode", format!("{mode:o}")));
56        }
57        let files = format!("{}/files", calls.path);
58        calls
59            .while_live(calls.client.bytes(Method::PUT, &files, &query, Some(data)))
60            .await
61            .map(drop)
62    }
63}