Skip to main content

moonpool_sim/storage/
provider.rs

1//! Simulated storage provider implementation.
2
3use super::file::SimStorageFile;
4use crate::sim::WeakSimWorld;
5use async_trait::async_trait;
6use moonpool_core::{OpenOptions, StorageProvider};
7use std::io;
8use std::net::IpAddr;
9
10/// Simulated storage provider for deterministic testing.
11///
12/// Each provider is scoped to a specific process IP address. Files opened
13/// through this provider are tagged with the owner IP, enabling per-process
14/// fault injection and storage isolation.
15///
16/// # Example
17///
18/// ```ignore
19/// let sim = SimWorld::new();
20/// let ip: IpAddr = "10.0.1.1".parse().unwrap();
21/// let provider = SimStorageProvider::new(sim.weak(), ip);
22///
23/// let file = provider.open("test.txt", OpenOptions::create_write()).await?;
24/// ```
25#[derive(Debug, Clone)]
26pub struct SimStorageProvider {
27    sim: WeakSimWorld,
28    /// IP address of the process that owns files opened through this provider.
29    owner_ip: IpAddr,
30}
31
32impl SimStorageProvider {
33    /// Create a new simulated storage provider scoped to a process IP.
34    pub fn new(sim: WeakSimWorld, owner_ip: IpAddr) -> Self {
35        Self { sim, owner_ip }
36    }
37}
38
39#[async_trait(?Send)]
40impl StorageProvider for SimStorageProvider {
41    type File = SimStorageFile;
42
43    async fn open(&self, path: &str, options: OpenOptions) -> io::Result<Self::File> {
44        let sim = self
45            .sim
46            .upgrade()
47            .map_err(|_| io::Error::other("simulation shutdown"))?;
48
49        let file_id = sim.open_file(path, options, 0, self.owner_ip)?;
50
51        Ok(SimStorageFile::new(self.sim.clone(), file_id))
52    }
53
54    async fn exists(&self, path: &str) -> io::Result<bool> {
55        let sim = self
56            .sim
57            .upgrade()
58            .map_err(|_| io::Error::other("simulation shutdown"))?;
59        Ok(sim.file_exists(path))
60    }
61
62    async fn delete(&self, path: &str) -> io::Result<()> {
63        let sim = self
64            .sim
65            .upgrade()
66            .map_err(|_| io::Error::other("simulation shutdown"))?;
67        sim.delete_file(path)?;
68        Ok(())
69    }
70
71    async fn rename(&self, from: &str, to: &str) -> io::Result<()> {
72        let sim = self
73            .sim
74            .upgrade()
75            .map_err(|_| io::Error::other("simulation shutdown"))?;
76        sim.rename_file(from, to)?;
77        Ok(())
78    }
79}