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