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