Skip to main content

docker_storage/
lib.rs

1#![warn(missing_docs)]
2
3use docker_types::DockerError;
4use std::path::{Path, PathBuf};
5use tokio::fs;
6
7/// 结果类型
8pub type StorageResult<T> = std::result::Result<T, DockerError>;
9
10pub struct StorageManager {
11    base_path: PathBuf,
12}
13
14impl StorageManager {
15    pub fn new() -> StorageResult<Self> {
16        let base_path = Self::get_base_path()?;
17        Ok(Self { base_path })
18    }
19
20    pub async fn ensure_directories(&self) -> StorageResult<()> {
21        let directories = [
22            &self.base_path,
23            &self.containers_path()?,
24            &self.images_path()?,
25            &self.volumes_path()?,
26            &self.tmp_path()?,
27        ];
28
29        for dir in directories {
30            if !dir.exists() {
31                fs::create_dir_all(dir).await?;
32            }
33        }
34
35        Ok(())
36    }
37
38    pub fn containers_path(&self) -> StorageResult<PathBuf> {
39        Ok(self.base_path.join("containers"))
40    }
41
42    pub fn container_path(&self, container_id: &str) -> StorageResult<PathBuf> {
43        Ok(self.containers_path()?.join(container_id))
44    }
45
46    pub fn images_path(&self) -> StorageResult<PathBuf> {
47        Ok(self.base_path.join("images"))
48    }
49
50    pub fn image_path(&self, image_id: &str) -> StorageResult<PathBuf> {
51        Ok(self.images_path()?.join(image_id))
52    }
53
54    pub fn volumes_path(&self) -> StorageResult<PathBuf> {
55        Ok(self.base_path.join("volumes"))
56    }
57
58    pub fn volume_path(&self, volume_id: &str) -> StorageResult<PathBuf> {
59        Ok(self.volumes_path()?.join(volume_id))
60    }
61
62    pub fn tmp_path(&self) -> StorageResult<PathBuf> {
63        Ok(self.base_path.join("tmp"))
64    }
65
66    pub fn get_base_path() -> StorageResult<PathBuf> {
67        #[cfg(windows)]
68        {
69            let app_data =
70                std::env::var("APPDATA").map_err(|_| DockerError::config_missing("APPDATA"))?;
71            Ok(PathBuf::from(app_data).join("DockerCrab"))
72        }
73
74        #[cfg(target_os = "linux")]
75        {
76            let home = std::env::var("HOME").map_err(|_| DockerError::config_missing("HOME"))?;
77            Ok(PathBuf::from(home).join(".docker-crab"))
78        }
79
80        #[cfg(target_os = "macos")]
81        {
82            let home = std::env::var("HOME").map_err(|_| DockerError::config_missing("HOME"))?;
83            Ok(PathBuf::from(home)
84                .join("Library")
85                .join("Application Support")
86                .join("DockerCrab"))
87        }
88    }
89
90    pub async fn create_file(&self, path: &Path, content: &[u8]) -> StorageResult<()> {
91        fs::write(path, content).await?;
92        Ok(())
93    }
94
95    pub async fn read_file(&self, path: &Path) -> StorageResult<Vec<u8>> {
96        let content = fs::read(path).await?;
97        Ok(content)
98    }
99
100    pub async fn remove_file(&self, path: &Path) -> StorageResult<()> {
101        if path.exists() {
102            fs::remove_file(path).await?;
103        }
104        Ok(())
105    }
106
107    pub async fn remove_directory(&self, path: &Path) -> StorageResult<()> {
108        if path.exists() {
109            fs::remove_dir_all(path).await?;
110        }
111        Ok(())
112    }
113}