noosphere_into/write/
memory.rs1use std::{
2 collections::BTreeMap,
3 path::{Path, PathBuf},
4 sync::Arc,
5};
6
7use super::WriteTargetConditionalSend;
8use anyhow::Result;
9use async_trait::async_trait;
10use futures::Future;
11use tokio::io::AsyncRead;
12use tokio::io::AsyncReadExt;
13use tokio::sync::Mutex;
14
15use super::WriteTarget;
16
17#[derive(Default, Clone)]
19pub struct MemoryWriteTarget {
20 vfs: Arc<Mutex<BTreeMap<PathBuf, Vec<u8>>>>,
21 aliases: Arc<Mutex<BTreeMap<PathBuf, PathBuf>>>,
22}
23
24impl MemoryWriteTarget {
25 pub async fn resolve_symlink(&self, path: &Path) -> Option<PathBuf> {
26 let aliases = self.aliases.lock().await;
27 aliases.get(path).cloned()
28 }
29
30 pub async fn read(&self, path: &Path) -> Option<Vec<u8>> {
31 let aliases = self.aliases.lock().await;
32
33 let path = if let Some(alias) = aliases.get(path) {
34 alias
35 } else {
36 path
37 };
38
39 self.vfs.lock().await.get(path).cloned()
40 }
41}
42
43#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
44#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
45impl WriteTarget for MemoryWriteTarget {
46 async fn exists(&self, path: &Path) -> Result<bool> {
47 Ok(self.vfs.lock().await.contains_key(path))
48 }
49
50 async fn write<R>(&self, path: &Path, mut contents: R) -> Result<()>
51 where
52 R: AsyncRead + Unpin + WriteTargetConditionalSend,
53 {
54 let mut buffer = Vec::new();
55 contents.read_to_end(&mut buffer).await?;
56 self.vfs.lock().await.insert(path.to_path_buf(), buffer);
57 Ok(())
58 }
59
60 async fn symlink(&self, src: &Path, dst: &Path) -> Result<()> {
61 let mut aliases = self.aliases.lock().await;
62 aliases.insert(dst.to_path_buf(), src.to_path_buf());
63 Ok(())
64 }
65
66 async fn spawn<F>(future: F) -> Result<()>
67 where
68 F: Future<Output = Result<()>> + WriteTargetConditionalSend + 'static,
69 {
70 future.await?;
71 Ok(())
72 }
73}