tenda_os_platform/
lib.rs

1use chrono::Local;
2use std::io::Write;
3
4#[derive(Debug)]
5pub struct Platform;
6
7fn map_file_error_kind(kind: std::io::ErrorKind) -> tenda_runtime::FileErrorKind {
8    use std::io;
9    use tenda_runtime::FileErrorKind;
10
11    match kind {
12        io::ErrorKind::NotFound => FileErrorKind::NotFound,
13        io::ErrorKind::PermissionDenied => FileErrorKind::PermissionDenied,
14        io::ErrorKind::AlreadyExists => FileErrorKind::AlreadyExists,
15        io::ErrorKind::Other => FileErrorKind::Other,
16        _ => FileErrorKind::Other,
17    }
18}
19
20impl tenda_runtime::Platform for Platform {
21    fn println(&self, message: &str) {
22        println!("{}", message);
23    }
24
25    fn print(&self, message: &str) {
26        print!("{}", message);
27
28        std::io::stdout().flush().unwrap();
29    }
30
31    fn write(&self, message: &str) {
32        print!("{}", message);
33    }
34
35    fn rand(&self) -> f64 {
36        rand::random()
37    }
38
39    fn read_file(&self, path: &str) -> Result<String, tenda_runtime::FileErrorKind> {
40        match std::fs::read_to_string(path) {
41            Ok(content) => Ok(content),
42            Err(error) => Err(map_file_error_kind(error.kind())),
43        }
44    }
45
46    fn write_file(&self, path: &str, content: &str) -> Result<(), tenda_runtime::FileErrorKind> {
47        match std::fs::write(path, content) {
48            Ok(_) => Ok(()),
49            Err(error) => Err(map_file_error_kind(error.kind())),
50        }
51    }
52
53    fn remove_file(&self, path: &str) -> Result<(), tenda_runtime::FileErrorKind> {
54        match std::fs::remove_file(path) {
55            Ok(_) => Ok(()),
56            Err(error) => Err(map_file_error_kind(error.kind())),
57        }
58    }
59
60    fn list_files(&self, path: &str) -> Result<Vec<String>, tenda_runtime::FileErrorKind> {
61        match std::fs::read_dir(path) {
62            Ok(entries) => Ok(entries
63                .filter_map(|entry| entry.ok().map(|entry| entry.file_name()))
64                .map(|name| name.to_string_lossy().to_string())
65                .collect()),
66            Err(error) => Err(map_file_error_kind(error.kind())),
67        }
68    }
69
70    fn create_dir(&self, path: &str) -> Result<(), tenda_runtime::FileErrorKind> {
71        match std::fs::create_dir(path) {
72            Ok(_) => Ok(()),
73            Err(error) => Err(map_file_error_kind(error.kind())),
74        }
75    }
76
77    fn remove_dir(&self, path: &str) -> Result<(), tenda_runtime::FileErrorKind> {
78        match std::fs::remove_dir(path) {
79            Ok(_) => Ok(()),
80            Err(error) => Err(map_file_error_kind(error.kind())),
81        }
82    }
83
84    fn list_dirs(&self, path: &str) -> Result<Vec<String>, tenda_runtime::FileErrorKind> {
85        match std::fs::read_dir(path) {
86            Ok(entries) => Ok(entries
87                .filter_map(|entry| entry.ok().map(|entry| entry.file_name()))
88                .map(|name| name.to_string_lossy().to_string())
89                .collect()),
90            Err(error) => Err(map_file_error_kind(error.kind())),
91        }
92    }
93
94    fn current_dir(&self) -> Result<String, tenda_runtime::FileErrorKind> {
95        match std::env::current_dir() {
96            Ok(path) => Ok(path.to_string_lossy().to_string()),
97            Err(error) => Err(map_file_error_kind(error.kind())),
98        }
99    }
100
101    fn file_append(&self, path: &str, content: &str) -> Result<(), tenda_runtime::FileErrorKind> {
102        match std::fs::OpenOptions::new().append(true).open(path) {
103            Ok(mut file) => match file.write_all(content.as_bytes()) {
104                Ok(_) => Ok(()),
105                Err(error) => Err(map_file_error_kind(error.kind())),
106            },
107            Err(error) => Err(map_file_error_kind(error.kind())),
108        }
109    }
110
111    fn args(&self) -> Vec<String> {
112        std::env::args().collect()
113    }
114
115    fn exit(&self, code: i32) {
116        std::process::exit(code);
117    }
118
119    fn sleep(&self, seconds: f64) {
120        std::thread::sleep(std::time::Duration::from_secs_f64(seconds));
121    }
122
123    fn date_now(&self) -> i64 {
124        Local::now().timestamp_millis()
125    }
126
127    fn timezone_offset(&self) -> i32 {
128        Local::now().offset().local_minus_utc()
129    }
130
131    fn read_line(&self) -> String {
132        let mut input = String::new();
133        std::io::stdin().read_line(&mut input).unwrap();
134        input.trim_end().to_string()
135    }
136}