tauri_plugin_android_fs/models/
file_uri.rs

1use serde::{Deserialize, Serialize};
2use crate::*;
3
4
5/// Path to represent a file or directory.
6/// 
7/// # Note
8/// For compatibility, an interconversion to [`tauri_plugin_fs::FilePath`] is implemented, such as follwing.  
9/// This is lossy and also not guaranteed to work properly with other plugins.  
10/// However, reading and writing files by official [`tauri_plugin_fs`] etc. should work well.  
11/// ```ignore
12/// use tauri_plugin_android_fs::FileUri;
13/// use tauri_plugin_fs::FilePath;
14/// 
15/// let uri: FileUri = unimplemented!();
16/// let path: FilePath = uri.into();
17/// let uri: FileUri = path.into();
18/// ```
19/// 
20/// # Typescript type
21/// ```typescript
22/// type FileUri = {
23///     uri: string, // This can use as path for official tauri_plugin_fs
24///     documentTopTreeUri: string | null
25/// }
26/// ```
27#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
28#[serde(rename_all = "camelCase")]
29pub struct FileUri {
30    /// `file://` or `content://` URI of file or directory.
31    pub uri: String,
32
33    /// Only files/directories under the directory obtained by `FilePicker::pick_dir` will own this.
34    pub document_top_tree_uri: Option<String>,
35}
36
37#[allow(unused)]
38impl FileUri {
39
40    /// This is same as [`FileUri::to_json_string`]
41    #[deprecated = "Confusing name. Use FileUri::to_json_string instead"]
42    pub fn to_string(&self) -> Result<String> {
43        serde_json::to_string(self).map_err(Into::into)
44    }
45
46    /// This is same as [`FileUri::from_json_str`]
47    #[deprecated = "Confusing name. Use FileUri::from_json_str instead"]
48    pub fn from_str(s: &str) -> Result<Self> {
49        serde_json::from_str(s).map_err(Into::into)
50    }
51
52    pub fn to_json_string(&self) -> Result<String> {
53        serde_json::to_string(self).map_err(Into::into)
54    }
55
56    pub fn from_json_str(json: impl AsRef<str>) -> Result<Self> {
57        serde_json::from_str(json.as_ref()).map_err(Into::into)
58    }
59
60    pub fn to_bytes(&self) -> Result<Vec<u8>> {
61        serde_json::to_vec(self).map_err(Into::into)
62    }
63
64    pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result<Self> {
65        serde_json::from_slice(bytes.as_ref()).map_err(Into::into)
66    }
67
68    pub fn from_path(path: impl AsRef<std::path::Path>) -> Self {
69        Self { uri: format!("file://{}", path.as_ref().to_string_lossy()), document_top_tree_uri: None }
70    }
71
72    pub(crate) fn as_path(&self) -> Option<&std::path::Path> {
73        if self.uri.starts_with("file://") {
74            return Some(std::path::Path::new(self.uri.trim_start_matches("file://")))
75        }
76        None
77    }
78
79    pub(crate) fn is_content_scheme(&self) -> bool {
80        self.uri.starts_with("content://")
81    }
82}
83
84impl From<&std::path::Path> for FileUri {
85
86    fn from(path: &std::path::Path) -> Self {
87        Self::from_path(path)
88    }
89}
90
91impl From<&std::path::PathBuf> for FileUri {
92
93    fn from(path: &std::path::PathBuf) -> Self {
94        Self::from_path(path)
95    }
96}
97
98impl From<std::path::PathBuf> for FileUri {
99
100    fn from(path: std::path::PathBuf) -> Self {
101        Self::from_path(path)
102    }
103}
104
105#[cfg(feature = "tauri-plugin-fs")]
106impl From<tauri_plugin_fs::FilePath> for FileUri {
107
108    fn from(value: tauri_plugin_fs::FilePath) -> Self {
109        match value {
110            tauri_plugin_fs::FilePath::Url(url) => Self { uri: url.to_string(), document_top_tree_uri: None },
111            tauri_plugin_fs::FilePath::Path(path_buf) => path_buf.into(),
112        }
113    }
114}
115
116#[cfg(feature = "tauri-plugin-fs")]
117impl From<FileUri> for tauri_plugin_fs::FilePath {
118
119    fn from(value: FileUri) -> Self {
120        type NeverErr<T> = std::result::Result::<T, std::convert::Infallible>;
121        NeverErr::unwrap(value.uri.parse())
122    }
123}