Skip to main content

ohos_resource_manager_binding/
lib.rs

1use ohos_resource_manager_sys::{
2    ArkUI_DrawableDescriptor, OH_ResourceManager_GetDrawableDescriptor,
3    OH_ResourceManager_GetDrawableDescriptorByName, OH_ResourceManager_GetMedia,
4    OH_ResourceManager_GetMediaBase64, OH_ResourceManager_GetMediaBase64ByName,
5    OH_ResourceManager_GetMediaByName, ResourceManager_ErrorCode_SUCCESS,
6};
7use std::ffi::CString;
8use std::ptr;
9
10use std::ptr::NonNull;
11
12#[cfg(feature = "napi")]
13use napi_ohos::{bindgen_prelude::Object, Env, JsValue};
14#[cfg(feature = "napi")]
15use ohos_resource_manager_sys::OH_ResourceManager_InitNativeResourceManager;
16
17use ohos_resource_manager_sys::{
18    NativeResourceManager, OH_ResourceManager_IsRawDir,
19    OH_ResourceManager_ReleaseNativeResourceManager,
20};
21
22mod error;
23mod info;
24mod raw_dir;
25
26pub use error::*;
27pub use info::*;
28pub use raw_dir::*;
29
30/// Resource Manager
31pub struct ResourceManager {
32    pub resource_manager: NonNull<NativeResourceManager>,
33}
34
35impl ResourceManager {
36    /// Use the resource manager from arkts to create a raw file manager.
37    /// Be aware that none of these methods are thread-safe.
38    /// ### Example
39    /// ```no_run
40    /// use napi_derive_ohos::napi;
41    /// use napi_ohos::{bindgen_prelude::Object, Env};
42    /// use ohos_raw_binding::Raw;
43    ///
44    /// #[napi]
45    /// pub fn raw_example(
46    ///     env: Env,
47    ///     #[napi(ts_arg_type = "resourceManager.ResourceManager")] resource_manager: Object,
48    /// ) -> i32 {
49    ///     let raw_manager = Raw::new(env, resource_manager);
50    ///     let raw_dir = raw_manager.open_dir("");
51    ///     let count = raw_dir.count();
52    ///     count
53    /// }
54    /// ```
55    #[cfg(feature = "napi")]
56    pub fn new(env: Env, resource_manager: Object) -> Self {
57        let raw = unsafe {
58            OH_ResourceManager_InitNativeResourceManager(env.raw(), resource_manager.raw())
59        };
60
61        #[cfg(debug_assertions)]
62        assert!(!raw.is_null(), "Raw is null");
63
64        ResourceManager {
65            resource_manager: unsafe { NonNull::new_unchecked(raw) },
66        }
67    }
68
69    pub fn from_raw(raw: *mut NativeResourceManager) -> Self {
70        #[cfg(debug_assertions)]
71        assert!(!raw.is_null(), "Raw is null");
72
73        ResourceManager {
74            resource_manager: unsafe { NonNull::new_unchecked(raw) },
75        }
76    }
77
78    /// get raw file dirs
79    pub fn open_dir<S: AsRef<str>>(
80        &self,
81        path: S,
82        recursive: bool,
83    ) -> Result<RawDir, RawFileError> {
84        Ok(RawDir::from_raw(
85            self.resource_manager,
86            path.as_ref().to_string(),
87            recursive,
88        ))
89    }
90
91    pub fn is_raw_dir<S: AsRef<str>>(&self, path: S) -> bool {
92        let dir = CString::new(path.as_ref()).expect("Can't crate CString.");
93        unsafe { OH_ResourceManager_IsRawDir(self.resource_manager.as_ptr(), dir.as_ptr().cast()) }
94    }
95
96    pub fn drawable_descriptor(
97        &self,
98        id: u32,
99        density: Option<ScreenDensity>,
100        icon_type: Option<IconType>,
101    ) -> Result<*mut *mut ArkUI_DrawableDescriptor, RawFileError> {
102        let use_density = density.unwrap_or_default();
103        let use_icon = icon_type.unwrap_or_default();
104        let ret = Box::into_raw(Box::new(ptr::null_mut()));
105        let code = unsafe {
106            OH_ResourceManager_GetDrawableDescriptor(
107                self.resource_manager.as_ptr(),
108                id,
109                ret,
110                use_density.into(),
111                use_icon.into(),
112            )
113        };
114        if code == ResourceManager_ErrorCode_SUCCESS {
115            Ok(ret)
116        } else {
117            Err(RawFileError::FfiInnerError(format!(
118                "Drawable descriptor by name failed: {}",
119                code
120            )))
121        }
122    }
123
124    pub fn drawable_descriptor_by_name(
125        &self,
126        name: String,
127        density: Option<ScreenDensity>,
128        icon_type: Option<IconType>,
129    ) -> Result<*mut *mut ArkUI_DrawableDescriptor, RawFileError> {
130        let use_name = CString::new(name).expect("Create CString failed");
131        let use_density = density.unwrap_or_default();
132        let use_icon = icon_type.unwrap_or_default();
133        let ret = Box::into_raw(Box::new(ptr::null_mut()));
134        let code = unsafe {
135            OH_ResourceManager_GetDrawableDescriptorByName(
136                self.resource_manager.as_ptr(),
137                use_name.as_ptr().cast(),
138                ret,
139                use_density.into(),
140                use_icon.into(),
141            )
142        };
143        if code == ResourceManager_ErrorCode_SUCCESS {
144            Ok(ret)
145        } else {
146            Err(RawFileError::FfiInnerError(format!(
147                "Drawable descriptor by name failed: {}",
148                code
149            )))
150        }
151    }
152
153    pub fn media(
154        &self,
155        res_id: u32,
156        density: Option<ScreenDensity>,
157    ) -> Result<Vec<u8>, RawFileError> {
158        let mut ret: Vec<u8> = Vec::new();
159        let mut len = 0;
160        let use_density = density.unwrap_or_default();
161        let code = unsafe {
162            OH_ResourceManager_GetMedia(
163                self.resource_manager.as_ptr(),
164                res_id,
165                ret.as_mut_ptr().cast(),
166                &mut len,
167                use_density.into(),
168            )
169        };
170        if code == ResourceManager_ErrorCode_SUCCESS {
171            Ok(ret)
172        } else {
173            Err(RawFileError::FfiInnerError(format!(
174                "Media failed: {}",
175                code
176            )))
177        }
178    }
179
180    pub fn media_base64(
181        &self,
182        res_id: u32,
183        density: Option<ScreenDensity>,
184    ) -> Result<Vec<u8>, RawFileError> {
185        let mut ret: Vec<u8> = Vec::new();
186        let mut len = 0;
187        let use_density = density.unwrap_or_default();
188        let code = unsafe {
189            OH_ResourceManager_GetMediaBase64(
190                self.resource_manager.as_ptr(),
191                res_id,
192                ret.as_mut_ptr().cast(),
193                &mut len,
194                use_density.into(),
195            )
196        };
197        if code == ResourceManager_ErrorCode_SUCCESS {
198            Ok(ret)
199        } else {
200            Err(RawFileError::FfiInnerError(format!(
201                "Media base64 failed: {}",
202                code
203            )))
204        }
205    }
206
207    pub fn media_by_name(
208        &self,
209        name: String,
210        density: Option<ScreenDensity>,
211    ) -> Result<Vec<u8>, RawFileError> {
212        let mut ret: Vec<u8> = Vec::new();
213        let mut len = 0;
214        let use_density = density.unwrap_or_default();
215        let use_name = CString::new(name).expect("Create CString failed");
216
217        let code = unsafe {
218            OH_ResourceManager_GetMediaByName(
219                self.resource_manager.as_ptr(),
220                use_name.as_ptr().cast(),
221                ret.as_mut_ptr().cast(),
222                &mut len,
223                use_density.into(),
224            )
225        };
226        if code == ResourceManager_ErrorCode_SUCCESS {
227            Ok(ret)
228        } else {
229            Err(RawFileError::FfiInnerError(format!(
230                "Media by name failed: {}",
231                code
232            )))
233        }
234    }
235
236    pub fn media_base64_by_name(
237        &self,
238        name: String,
239        density: Option<ScreenDensity>,
240    ) -> Result<Vec<u8>, RawFileError> {
241        let mut ret: Vec<u8> = Vec::new();
242        let mut len = 0;
243        let use_density = density.unwrap_or_default();
244        let use_name = CString::new(name).expect("Create CString failed");
245
246        let code = unsafe {
247            OH_ResourceManager_GetMediaBase64ByName(
248                self.resource_manager.as_ptr(),
249                use_name.as_ptr().cast(),
250                ret.as_mut_ptr().cast(),
251                &mut len,
252                use_density.into(),
253            )
254        };
255        if code == ResourceManager_ErrorCode_SUCCESS {
256            Ok(ret)
257        } else {
258            Err(RawFileError::FfiInnerError(format!(
259                "Media base64 by name failed: {}",
260                code
261            )))
262        }
263    }
264}
265
266unsafe impl Send for ResourceManager {}
267unsafe impl Sync for ResourceManager {}
268
269impl Drop for ResourceManager {
270    fn drop(&mut self) {
271        unsafe {
272            OH_ResourceManager_ReleaseNativeResourceManager(self.resource_manager.as_ptr());
273        }
274    }
275}