ohos_fileuri_binding/lib.rs
1//! OpenHarmony File URI bindings for Rust
2//!
3//! This crate provides safe Rust bindings for OpenHarmony's file URI operations,
4//! allowing conversion between file paths and URIs, URI validation, and directory operations.
5
6pub mod error;
7
8pub use error::FileUriError;
9
10use std::ffi::{CStr, CString};
11use std::os::raw::c_char;
12use std::ptr;
13
14use error::error_from_code;
15use ohos_fileuri_sys::*;
16
17/// Get URI from file path
18///
19/// Converts a file system path to a file URI.
20///
21/// # Arguments
22///
23/// * `path` - The file system path
24///
25/// # Returns
26///
27/// Returns the URI string on success, or an error on failure.
28///
29/// # Example
30///
31/// ```no_run
32/// use ohos_fileuri_binding::get_uri_from_path;
33///
34/// let uri = get_uri_from_path("/data/storage/el2/base/files/test.txt")?;
35/// println!("URI: {}", uri);
36/// # Ok::<(), ohos_fileuri_binding::FileUriError>(())
37/// ```
38pub fn get_uri_from_path(path: &str) -> std::result::Result<String, FileUriError> {
39 let c_path = CString::new(path).map_err(|_| FileUriError::NullByteError)?;
40 let mut result: *mut c_char = ptr::null_mut();
41
42 let code =
43 unsafe { OH_FileUri_GetUriFromPath(c_path.as_ptr(), path.len() as u32, &mut result) };
44
45 if code == FileManagement_ErrCode_ERR_OK {
46 if result.is_null() {
47 return Err(FileUriError::ConversionError);
48 }
49
50 let uri = unsafe {
51 let c_str = CStr::from_ptr(result);
52 let rust_str = c_str
53 .to_str()
54 .map_err(|_| FileUriError::ConversionError)?
55 .to_string();
56 libc::free(result as *mut _);
57 rust_str
58 };
59
60 Ok(uri)
61 } else {
62 if !result.is_null() {
63 unsafe { libc::free(result as *mut _) };
64 }
65 Err(error_from_code(code))
66 }
67}
68
69/// Get file path from URI
70///
71/// Converts a file URI to a file system path.
72///
73/// # Arguments
74///
75/// * `uri` - The file URI
76///
77/// # Returns
78///
79/// Returns the file system path on success, or an error on failure.
80///
81/// # Example
82///
83/// ```no_run
84/// use ohos_fileuri_binding::get_path_from_uri;
85///
86/// let path = get_path_from_uri("file://com.example.app/data/storage/el2/base/files/test.txt")?;
87/// println!("Path: {}", path);
88/// # Ok::<(), ohos_fileuri_binding::FileUriError>(())
89/// ```
90pub fn get_path_from_uri(uri: &str) -> std::result::Result<String, FileUriError> {
91 let c_uri = CString::new(uri).map_err(|_| FileUriError::NullByteError)?;
92 let mut result: *mut c_char = ptr::null_mut();
93
94 let code = unsafe { OH_FileUri_GetPathFromUri(c_uri.as_ptr(), uri.len() as u32, &mut result) };
95
96 if code == FileManagement_ErrCode_ERR_OK {
97 if result.is_null() {
98 return Err(FileUriError::ConversionError);
99 }
100
101 let path = unsafe {
102 let c_str = CStr::from_ptr(result);
103 let rust_str = c_str
104 .to_str()
105 .map_err(|_| FileUriError::ConversionError)?
106 .to_string();
107 libc::free(result as *mut _);
108 rust_str
109 };
110
111 Ok(path)
112 } else {
113 if !result.is_null() {
114 unsafe { libc::free(result as *mut _) };
115 }
116 Err(error_from_code(code))
117 }
118}
119
120/// Get the full directory URI from a file or directory URI
121///
122/// Gets the URI of the directory where the given URI is located.
123///
124/// # Arguments
125///
126/// * `uri` - The file or directory URI
127///
128/// # Returns
129///
130/// Returns the directory URI on success, or an error on failure.
131///
132/// # Example
133///
134/// ```no_run
135/// use ohos_fileuri_binding::get_full_directory_uri;
136///
137/// let dir_uri = get_full_directory_uri("file://com.example.app/data/storage/el2/base/files/test.txt")?;
138/// println!("Directory URI: {}", dir_uri);
139/// # Ok::<(), ohos_fileuri_binding::FileUriError>(())
140/// ```
141pub fn get_full_directory_uri(uri: &str) -> std::result::Result<String, FileUriError> {
142 let c_uri = CString::new(uri).map_err(|_| FileUriError::NullByteError)?;
143 let mut result: *mut c_char = ptr::null_mut();
144
145 let code =
146 unsafe { OH_FileUri_GetFullDirectoryUri(c_uri.as_ptr(), uri.len() as u32, &mut result) };
147
148 if code == FileManagement_ErrCode_ERR_OK {
149 if result.is_null() {
150 return Err(FileUriError::ConversionError);
151 }
152
153 let dir_uri = unsafe {
154 let c_str = CStr::from_ptr(result);
155 let rust_str = c_str
156 .to_str()
157 .map_err(|_| FileUriError::ConversionError)?
158 .to_string();
159 libc::free(result as *mut _);
160 rust_str
161 };
162
163 Ok(dir_uri)
164 } else {
165 if !result.is_null() {
166 unsafe { libc::free(result as *mut _) };
167 }
168 Err(error_from_code(code))
169 }
170}
171
172/// Check if the given URI is valid
173///
174/// Validates whether the provided string is a valid file URI.
175///
176/// # Arguments
177///
178/// * `uri` - The URI to validate
179///
180/// # Returns
181///
182/// Returns `true` if the URI is valid, `false` otherwise.
183///
184/// # Example
185///
186/// ```no_run
187/// use ohos_fileuri_binding::is_valid_uri;
188///
189/// if is_valid_uri("file://com.example.app/data/storage/el2/base/files/test.txt") {
190/// println!("URI is valid");
191/// } else {
192/// println!("URI is invalid");
193/// }
194/// ```
195pub fn is_valid_uri(uri: &str) -> bool {
196 let Ok(c_uri) = CString::new(uri) else {
197 return false;
198 };
199
200 unsafe { OH_FileUri_IsValidUri(c_uri.as_ptr(), uri.len() as u32) }
201}
202
203/// Get file name from URI (API 13+)
204///
205/// Extracts the file name (last segment) from a file URI.
206/// Note: This function does not support media type URIs.
207///
208/// # Arguments
209///
210/// * `uri` - The file URI
211///
212/// # Returns
213///
214/// Returns the file name on success, or an error on failure.
215///
216/// # Example
217///
218/// ```no_run
219/// use ohos_fileuri_binding::get_file_name;
220///
221/// # #[cfg(feature = "api-13")]
222/// let filename = get_file_name("file://com.example.app/data/storage/el2/base/files/test.txt")?;
223/// # #[cfg(feature = "api-13")]
224/// println!("File name: {}", filename);
225/// # Ok::<(), ohos_fileuri_binding::FileUriError>(())
226/// ```
227#[cfg(feature = "api-13")]
228pub fn get_file_name(uri: &str) -> std::result::Result<String, FileUriError> {
229 let c_uri = CString::new(uri).map_err(|_| FileUriError::NullByteError)?;
230 let mut result: *mut c_char = ptr::null_mut();
231
232 let code = unsafe { OH_FileUri_GetFileName(c_uri.as_ptr(), uri.len() as u32, &mut result) };
233
234 if code == FileManagement_ErrCode_ERR_OK {
235 if result.is_null() {
236 return Err(FileUriError::ConversionError);
237 }
238
239 let filename = unsafe {
240 let c_str = CStr::from_ptr(result);
241 let rust_str = c_str
242 .to_str()
243 .map_err(|_| FileUriError::ConversionError)?
244 .to_string();
245 libc::free(result as *mut _);
246 rust_str
247 };
248
249 Ok(filename)
250 } else {
251 if !result.is_null() {
252 unsafe { libc::free(result as *mut _) };
253 }
254 Err(error_from_code(code))
255 }
256}