Skip to main content

rlobkit_dialogs/
picker.rs

1use crate::{RlobKitMode, RlobKitType};
2use rlobkit_core::{PlatformDirectory, PlatformFile, RlobKitError};
3use std::path::{Path, PathBuf};
4
5#[derive(Debug, Clone, Default)]
6pub struct OpenFileOptions {
7    pub file_type: RlobKitType,
8    pub mode: RlobKitMode,
9    pub title: Option<String>,
10    pub initial_directory: Option<PathBuf>,
11}
12
13#[derive(Debug, Clone, Default)]
14pub struct SaveFileOptions {
15    pub suggested_name: Option<String>,
16    pub extension: Option<String>,
17    pub title: Option<String>,
18    pub initial_directory: Option<PathBuf>,
19    pub file_type: Option<RlobKitType>,
20    #[cfg(target_arch = "wasm32")]
21    pub data: Option<Vec<u8>>,
22}
23
24#[derive(Debug, Clone, Default)]
25pub struct OpenDirectoryOptions {
26    pub title: Option<String>,
27    pub initial_directory: Option<PathBuf>,
28}
29
30pub struct RlobKit;
31
32impl RlobKit {
33    pub async fn open_file_picker(
34        opts: OpenFileOptions,
35    ) -> Result<Option<Vec<PlatformFile>>, RlobKitError> {
36        #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
37        {
38            return crate::desktop::open_file_picker(opts).await;
39        }
40
41        #[cfg(target_arch = "wasm32")]
42        {
43            return crate::wasm::open_file_picker(opts).await;
44        }
45
46        #[cfg(target_os = "android")]
47        {
48            return crate::android::open_file_picker(opts).await;
49        }
50
51        #[allow(unreachable_code)]
52        Err(RlobKitError::UnsupportedOperation(
53            "Unsupported platform".into(),
54        ))
55    }
56
57    pub async fn open_single_file(
58        file_type: RlobKitType,
59    ) -> Result<Option<PlatformFile>, RlobKitError> {
60        let result = Self::open_file_picker(OpenFileOptions {
61            file_type,
62            mode: RlobKitMode::Single,
63            ..Default::default()
64        })
65        .await?;
66        Ok(result.and_then(|v| v.into_iter().next()))
67    }
68
69    pub async fn open_directory_picker(
70        opts: OpenDirectoryOptions,
71    ) -> Result<Option<PlatformDirectory>, RlobKitError> {
72        #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
73        {
74            return crate::desktop::open_directory_picker(opts).await;
75        }
76
77        #[cfg(target_arch = "wasm32")]
78        {
79            return Err(RlobKitError::UnsupportedOperation(
80                "Directory picker not supported on WASM".into(),
81            ));
82        }
83
84        #[cfg(target_os = "android")]
85        {
86            return crate::android::open_directory_picker(opts).await;
87        }
88
89        #[allow(unreachable_code)]
90        Err(RlobKitError::UnsupportedOperation(
91            "Unsupported platform".into(),
92        ))
93    }
94
95    pub async fn open_file_saver(
96        opts: SaveFileOptions,
97    ) -> Result<Option<PlatformFile>, RlobKitError> {
98        #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
99        {
100            return crate::desktop::open_file_saver(opts).await;
101        }
102
103        #[cfg(target_arch = "wasm32")]
104        {
105            return crate::wasm::open_file_saver(opts).await;
106        }
107
108        #[cfg(target_os = "android")]
109        {
110            return crate::android::open_file_saver(opts).await;
111        }
112
113        #[allow(unreachable_code)]
114        Err(RlobKitError::UnsupportedOperation(
115            "Unsupported platform".into(),
116        ))
117    }
118
119    pub fn write_file_from_path(
120        target: &PlatformFile,
121        source_path: &Path,
122    ) -> Result<(), RlobKitError> {
123        #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
124        {
125            return crate::desktop::write_file_from_path(target, source_path);
126        }
127
128        #[cfg(target_arch = "wasm32")]
129        {
130            return crate::wasm::write_file_from_path(target, source_path);
131        }
132
133        #[cfg(target_os = "android")]
134        {
135            return crate::android::write_file_from_path(target, source_path);
136        }
137
138        #[allow(unreachable_code)]
139        Err(RlobKitError::UnsupportedOperation(
140            "Unsupported platform".into(),
141        ))
142    }
143
144    pub fn read_file_to_path(source: &PlatformFile, dest_path: &Path) -> Result<(), RlobKitError> {
145        #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
146        {
147            return crate::desktop::read_file_to_path(source, dest_path);
148        }
149
150        #[cfg(target_arch = "wasm32")]
151        {
152            return crate::wasm::read_file_to_path(source, dest_path);
153        }
154
155        #[cfg(target_os = "android")]
156        {
157            return crate::android::read_file_to_path(source, dest_path);
158        }
159
160        #[allow(unreachable_code)]
161        Err(RlobKitError::UnsupportedOperation(
162            "Unsupported platform".into(),
163        ))
164    }
165
166    pub async fn save_bytes(
167        opts: SaveFileOptions,
168        data: &[u8],
169    ) -> Result<Option<PlatformFile>, RlobKitError> {
170        #[cfg(target_os = "android")]
171        {
172            let target = Self::open_file_saver(opts).await?;
173            if let Some(file) = &target {
174                let temp_name = if file.name().is_empty() {
175                    "export.bin".to_string()
176                } else {
177                    file.name().to_string()
178                };
179                let temp = std::env::temp_dir().join(temp_name);
180                std::fs::write(&temp, data)?;
181                Self::write_file_from_path(file, &temp)?;
182                let _ = std::fs::remove_file(&temp);
183            }
184            return Ok(target);
185        }
186
187        #[cfg(target_arch = "wasm32")]
188        {
189            let mut wasm_opts = opts;
190            wasm_opts.data = Some(data.to_vec());
191            return Self::open_file_saver(wasm_opts).await;
192        }
193
194        #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
195        {
196            let target = Self::open_file_saver(opts).await?;
197            if let Some(file) = &target {
198                file.write_bytes(data)?;
199            }
200            return Ok(target);
201        }
202
203        #[allow(unreachable_code)]
204        Err(RlobKitError::UnsupportedOperation(
205            "Unsupported platform".into(),
206        ))
207    }
208}