Skip to main content

lingxia_platform/
unsupported.rs

1#![allow(clippy::manual_async_fn)]
2
3use std::future::Future;
4use std::io::Read;
5use std::path::{Path, PathBuf};
6
7use crate::error::PlatformError;
8use crate::traits::app_runtime::{AnimationType, AppRuntime, LxAppOpenMode, OpenUrlRequest};
9use crate::traits::device::{Device, DeviceHardware};
10use crate::traits::file::{
11    ChooseDirectoryRequest, ChooseFileRequest, FileDialogResult, FileService, OpenFileRequest,
12    RevealInFileManagerRequest,
13};
14use crate::traits::location::{Location, LocationRequestConfig};
15use crate::traits::media_interaction::{
16    ChooseMediaRequest, MediaInteraction, PreviewMediaRequest, SaveMediaRequest, ScanCodeRequest,
17};
18use crate::traits::media_runtime::{
19    CompressImageRequest, CompressVideoRequest, CompressedVideo, ExtractVideoThumbnailRequest,
20    ImageInfo, MediaRuntime, VideoInfo, VideoThumbnail,
21};
22use crate::traits::mouse::AppMouse;
23use crate::traits::network::Network;
24use crate::traits::pull_to_refresh::PullToRefresh;
25use crate::traits::screenshot::AppScreenshot;
26use crate::traits::secure_store::SecureStore;
27use crate::traits::share::{ShareRequest, ShareResult, ShareService};
28use crate::traits::stream_decoder::{VideoStreamDecoderHandle, VideoStreamDecoderManager};
29use crate::traits::ui::{ModalOptions, SurfacePresenter, ToastOptions, UIUpdate, UserFeedback};
30use crate::traits::update::UpdateService;
31use crate::traits::video_player::{VideoPlayerHandle, VideoPlayerManager};
32use crate::traits::wifi::Wifi;
33use crate::{AssetFileEntry, DeviceInfo, ScreenInfo};
34
35#[derive(Debug, Clone)]
36pub struct Platform {
37    data_dir: PathBuf,
38    cache_dir: PathBuf,
39    locale: String,
40}
41
42impl Default for Platform {
43    fn default() -> Self {
44        let base = std::env::temp_dir().join("lingxia");
45        Self {
46            data_dir: base.join("data"),
47            cache_dir: base.join("cache"),
48            locale: "en-US".to_string(),
49        }
50    }
51}
52
53impl Platform {
54    pub fn new(
55        data_dir: impl Into<PathBuf>,
56        cache_dir: impl Into<PathBuf>,
57        locale: impl Into<String>,
58    ) -> Result<Self, PlatformError> {
59        Ok(Self {
60            data_dir: data_dir.into(),
61            cache_dir: cache_dir.into(),
62            locale: locale.into(),
63        })
64    }
65}
66
67fn not_supported<T>(name: &str) -> Result<T, PlatformError> {
68    Err(PlatformError::NotSupported(format!(
69        "{name} is not supported on this platform"
70    )))
71}
72
73impl Device for Platform {
74    fn device_info(&self) -> DeviceInfo {
75        DeviceInfo {
76            brand: "unsupported".to_string(),
77            model: std::env::consts::OS.to_string(),
78            market_name: std::env::consts::OS.to_string(),
79            os_name: std::env::consts::OS.to_string(),
80            os_version: String::new(),
81        }
82    }
83
84    fn screen_info(&self) -> ScreenInfo {
85        ScreenInfo {
86            width: 0.0,
87            height: 0.0,
88            scale: 1.0,
89        }
90    }
91
92    fn vibrate(&self, _long: bool) -> Result<(), PlatformError> {
93        not_supported("vibrate")
94    }
95
96    fn make_phone_call(&self, _phone_number: &str) -> Result<(), PlatformError> {
97        not_supported("make_phone_call")
98    }
99}
100
101impl DeviceHardware for Platform {}
102impl SecureStore for Platform {}
103impl Network for Platform {}
104impl SurfacePresenter for Platform {}
105impl UpdateService for Platform {}
106impl Wifi for Platform {}
107impl AppScreenshot for Platform {}
108impl AppMouse for Platform {}
109
110impl FileService for Platform {
111    fn review_file(
112        &self,
113        _request: OpenFileRequest,
114    ) -> impl Future<Output = Result<(), PlatformError>> + Send {
115        async { not_supported("review_file") }
116    }
117
118    fn open_external(
119        &self,
120        _request: OpenFileRequest,
121    ) -> impl Future<Output = Result<(), PlatformError>> + Send {
122        async { not_supported("open_external") }
123    }
124
125    fn reveal_in_file_manager(
126        &self,
127        _request: RevealInFileManagerRequest,
128    ) -> impl Future<Output = Result<(), PlatformError>> + Send {
129        async { not_supported("reveal_in_file_manager") }
130    }
131
132    fn choose_file(
133        &self,
134        _request: ChooseFileRequest,
135    ) -> impl Future<Output = Result<FileDialogResult, PlatformError>> + Send {
136        async { not_supported("choose_file") }
137    }
138
139    fn choose_directory(
140        &self,
141        _request: ChooseDirectoryRequest,
142    ) -> impl Future<Output = Result<FileDialogResult, PlatformError>> + Send {
143        async { not_supported("choose_directory") }
144    }
145}
146
147impl Location for Platform {
148    fn is_location_enabled(&self) -> Result<bool, PlatformError> {
149        not_supported("is_location_enabled")
150    }
151
152    fn request_location(
153        &self,
154        _config: LocationRequestConfig,
155    ) -> impl Future<Output = Result<String, PlatformError>> + Send {
156        async { not_supported("request_location") }
157    }
158}
159
160impl MediaInteraction for Platform {
161    fn preview_media(&self, _request: PreviewMediaRequest) -> Result<(), PlatformError> {
162        not_supported("preview_media")
163    }
164
165    fn cancel_preview(&self, _callback_id: u64) -> Result<(), PlatformError> {
166        not_supported("cancel_preview")
167    }
168
169    fn choose_media(
170        &self,
171        _request: ChooseMediaRequest,
172    ) -> impl Future<Output = Result<String, PlatformError>> + Send {
173        async { not_supported("choose_media") }
174    }
175
176    fn scan_code(
177        &self,
178        _request: ScanCodeRequest,
179    ) -> impl Future<Output = Result<String, PlatformError>> + Send {
180        async { not_supported("scan_code") }
181    }
182
183    fn save_image_to_photos_album(
184        &self,
185        _request: SaveMediaRequest,
186    ) -> impl Future<Output = Result<(), PlatformError>> + Send {
187        async { not_supported("save_image_to_photos_album") }
188    }
189
190    fn save_video_to_photos_album(
191        &self,
192        _request: SaveMediaRequest,
193    ) -> impl Future<Output = Result<(), PlatformError>> + Send {
194        async { not_supported("save_video_to_photos_album") }
195    }
196}
197
198impl MediaRuntime for Platform {
199    fn copy_album_media_to_file(
200        &self,
201        _uri: &str,
202        _dest_path: &Path,
203        _kind: crate::traits::media_interaction::MediaKind,
204    ) -> Result<(), PlatformError> {
205        not_supported("copy_album_media_to_file")
206    }
207
208    fn get_image_info(&self, _uri: &str) -> Result<ImageInfo, PlatformError> {
209        not_supported("get_image_info")
210    }
211
212    fn compress_image(&self, _request: &CompressImageRequest) -> Result<PathBuf, PlatformError> {
213        not_supported("compress_image")
214    }
215
216    fn compress_video(&self, _request: &CompressVideoRequest) -> Result<(), PlatformError> {
217        not_supported("compress_video")
218    }
219
220    fn cancel_compress_video(&self, _callback_id: u64) -> Result<(), PlatformError> {
221        not_supported("cancel_compress_video")
222    }
223
224    fn get_video_info(&self, _uri: &str) -> Result<VideoInfo, PlatformError> {
225        not_supported("get_video_info")
226    }
227
228    fn extract_video_thumbnail(
229        &self,
230        _request: &ExtractVideoThumbnailRequest,
231    ) -> Result<VideoThumbnail, PlatformError> {
232        not_supported("extract_video_thumbnail")
233    }
234}
235
236impl ShareService for Platform {
237    fn share(
238        &self,
239        _request: ShareRequest,
240    ) -> impl Future<Output = Result<ShareResult, PlatformError>> + Send {
241        async { not_supported("share") }
242    }
243}
244
245impl UIUpdate for Platform {
246    fn update_navbar_ui(&self, _appid: String) -> Result<(), PlatformError> {
247        not_supported("update_navbar_ui")
248    }
249
250    fn update_tabbar_ui(&self, _appid: String) -> Result<(), PlatformError> {
251        not_supported("update_tabbar_ui")
252    }
253}
254
255impl UserFeedback for Platform {
256    fn show_toast(&self, _options: ToastOptions) -> Result<(), PlatformError> {
257        not_supported("show_toast")
258    }
259
260    fn hide_toast(&self) -> Result<(), PlatformError> {
261        not_supported("hide_toast")
262    }
263
264    fn show_modal(
265        &self,
266        _options: ModalOptions,
267    ) -> impl Future<Output = Result<String, PlatformError>> + Send {
268        async { not_supported("show_modal") }
269    }
270
271    fn show_action_sheet(
272        &self,
273        _options: Vec<String>,
274        _cancel_text: String,
275        _item_color: String,
276    ) -> impl Future<Output = Result<String, PlatformError>> + Send {
277        async { not_supported("show_action_sheet") }
278    }
279}
280
281impl PullToRefresh for Platform {
282    fn start_pull_down_refresh(&self, _app_id: &str, _path: &str) -> Result<(), PlatformError> {
283        not_supported("start_pull_down_refresh")
284    }
285
286    fn stop_pull_down_refresh(&self, _app_id: &str, _path: &str) -> Result<(), PlatformError> {
287        not_supported("stop_pull_down_refresh")
288    }
289}
290
291impl VideoPlayerManager for Platform {
292    fn bind_player(
293        &self,
294        _component_id: &str,
295    ) -> Result<Box<dyn VideoPlayerHandle>, PlatformError> {
296        not_supported("bind_player")
297    }
298}
299
300impl VideoStreamDecoderManager for Platform {
301    fn create_stream_decoder(
302        &self,
303        _component_id: &str,
304    ) -> Result<Box<dyn VideoStreamDecoderHandle>, PlatformError> {
305        not_supported("create_stream_decoder")
306    }
307}
308
309impl AppRuntime for Platform {
310    fn read_asset<'a>(&'a self, _path: &str) -> Result<Box<dyn Read + 'a>, PlatformError> {
311        not_supported("read_asset")
312    }
313
314    fn asset_dir_iter<'a>(
315        &'a self,
316        _asset_dir: &str,
317    ) -> Box<dyn Iterator<Item = Result<AssetFileEntry<'a>, PlatformError>> + 'a> {
318        Box::new(std::iter::once(not_supported("asset_dir_iter")))
319    }
320
321    fn app_data_dir(&self) -> PathBuf {
322        self.data_dir.clone()
323    }
324
325    fn app_cache_dir(&self) -> PathBuf {
326        self.cache_dir.clone()
327    }
328
329    fn get_app_identifier(&self) -> Result<String, PlatformError> {
330        not_supported("get_app_identifier")
331    }
332
333    fn get_system_locale(&self) -> &str {
334        &self.locale
335    }
336
337    fn show_lxapp(
338        &self,
339        _appid: String,
340        _path: String,
341        _session_id: u64,
342        _open_mode: LxAppOpenMode,
343        _panel_id: String,
344    ) -> Result<(), PlatformError> {
345        not_supported("show_lxapp")
346    }
347
348    fn hide_lxapp(&self, _appid: String, _session_id: u64) -> Result<(), PlatformError> {
349        not_supported("hide_lxapp")
350    }
351
352    fn exit(&self) -> Result<(), PlatformError> {
353        not_supported("exit")
354    }
355
356    fn navigate(
357        &self,
358        _appid: String,
359        _path: String,
360        _animation_type: AnimationType,
361    ) -> Result<(), PlatformError> {
362        not_supported("navigate")
363    }
364
365    fn open_url(&self, _req: OpenUrlRequest) -> Result<(), PlatformError> {
366        not_supported("open_url")
367    }
368
369    fn get_capsule_rect(&self) -> impl Future<Output = Result<String, PlatformError>> + Send {
370        async { not_supported("get_capsule_rect") }
371    }
372}