Skip to main content

cqlite_core/platform/
mod.rs

1//! Platform abstraction layer for cross-platform compatibility
2
3use crate::{Config, Result};
4
5pub mod fs;
6pub mod threading;
7pub mod time;
8
9/// Platform abstraction layer
10#[derive(Debug)]
11pub struct Platform {
12    /// File system abstraction
13    fs: fs::FileSystem,
14
15    /// Time utilities
16    time: time::TimeProvider,
17
18    /// Threading utilities
19    threading: threading::ThreadingProvider,
20
21    /// Configuration
22    config: Config,
23}
24
25impl Platform {
26    /// Create a new platform abstraction
27    pub async fn new(config: &Config) -> Result<Self> {
28        Ok(Self {
29            fs: fs::FileSystem::new().await?,
30            time: time::TimeProvider::new(),
31            threading: threading::ThreadingProvider::new(),
32            config: config.clone(),
33        })
34    }
35
36    /// Get file system abstraction
37    pub fn fs(&self) -> &fs::FileSystem {
38        &self.fs
39    }
40
41    /// Get time provider
42    pub fn time(&self) -> &time::TimeProvider {
43        &self.time
44    }
45
46    /// Get threading provider
47    pub fn threading(&self) -> &threading::ThreadingProvider {
48        &self.threading
49    }
50
51    /// Get configuration
52    pub fn config(&self) -> &Config {
53        &self.config
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use std::path::Path;
61    use tempfile::TempDir;
62
63    #[tokio::test]
64    async fn test_platform_creation() {
65        let config = Config::default();
66        let platform = Platform::new(&config).await.unwrap();
67
68        assert!(platform.fs().exists(Path::new(".")).await.unwrap());
69    }
70
71    #[tokio::test]
72    async fn test_file_system() {
73        let config = Config::default();
74        let platform = Platform::new(&config).await.unwrap();
75        let fs = platform.fs();
76
77        let temp_dir = TempDir::new().unwrap();
78        let test_file = temp_dir.path().join("test.txt");
79        let content = b"Hello, World!";
80
81        // Write file
82        fs.write_file(&test_file, content).await.unwrap();
83
84        // Check exists
85        assert!(fs.exists(&test_file).await.unwrap());
86
87        // Read file
88        let read_content = fs.read_file(&test_file).await.unwrap();
89        assert_eq!(read_content, content);
90
91        // Get file size
92        let size = fs.file_size(&test_file).await.unwrap();
93        assert_eq!(size, content.len() as u64);
94
95        // Remove file
96        fs.remove_file(&test_file).await.unwrap();
97        assert!(!fs.exists(&test_file).await.unwrap());
98    }
99
100    #[test]
101    fn test_time_provider() {
102        let time = time::TimeProvider::new();
103
104        let now_micros = time.now_micros();
105        let now_millis = time.now_millis();
106        let now_secs = time.now_secs();
107
108        assert!(now_micros > 0);
109        assert!(now_millis > 0);
110        assert!(now_secs > 0);
111
112        // Check relationships with tolerance for timing differences
113        // Allow for small variations due to multiple system calls
114        let micros_to_millis = now_micros / 1000;
115        let millis_to_secs = now_millis / 1000;
116
117        // Allow small tolerance for timing variations between system calls
118        let tolerance_ms: u64 = 5;
119        let tolerance_sec: u64 = 1;
120
121        assert!(
122            micros_to_millis >= now_millis.saturating_sub(tolerance_ms),
123            "micros_to_millis ({}) should be within {}ms of now_millis ({})",
124            micros_to_millis,
125            tolerance_ms,
126            now_millis
127        );
128        assert!(
129            millis_to_secs >= now_secs.saturating_sub(tolerance_sec),
130            "millis_to_secs ({}) should be within {}s of now_secs ({})",
131            millis_to_secs,
132            tolerance_sec,
133            now_secs
134        );
135    }
136
137    #[tokio::test]
138    async fn test_threading_provider() {
139        let threading = threading::ThreadingProvider::new();
140
141        let result = threading.execute_cpu_task(|| 42).await.unwrap();
142
143        assert_eq!(result, 42);
144
145        let result = threading
146            .execute_io_task(|| "hello".to_string())
147            .await
148            .unwrap();
149
150        assert_eq!(result, "hello");
151    }
152}