cranpose_services/
storage.rs1use std::{path::Path, sync::Arc};
5
6use crate::registry::ServiceRegistry;
7
8pub trait StorageSpace: Send + Sync {
10 fn available(&self, path: &Path) -> Option<u64>;
13}
14
15pub type StorageSpaceRef = Arc<dyn StorageSpace>;
16
17static PLATFORM_STORAGE_SPACE: ServiceRegistry<dyn StorageSpace> = ServiceRegistry::new();
18
19pub fn set_platform_storage_space(space: StorageSpaceRef) {
24 PLATFORM_STORAGE_SPACE.set(space);
25}
26
27pub fn available_storage(path: &Path) -> Option<u64> {
31 let existing = path.ancestors().find(|folder| folder.exists())?;
32 match PLATFORM_STORAGE_SPACE.get() {
33 Some(platform) => platform.available(existing),
34 None => file_system_available(existing),
35 }
36}
37
38#[cfg(unix)]
39fn file_system_available(path: &Path) -> Option<u64> {
40 let stat = rustix::fs::statvfs(path).ok()?;
41 Some(stat.f_bavail.saturating_mul(stat.f_frsize))
42}
43
44#[cfg(not(unix))]
45fn file_system_available(_path: &Path) -> Option<u64> {
46 None
47}
48
49#[cfg(test)]
50#[path = "tests/storage_tests.rs"]
51mod tests;