Skip to main content

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}