tauri_plugin_android_fs/api/models/
fs_uri.rs1use crate::*;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Hash, PartialEq, Eq, Deserialize, Serialize)]
16#[serde(rename_all = "camelCase")]
17pub struct FsUri {
18
19 pub uri: String,
24
25 pub document_top_tree_uri: Option<String>,
31}
32
33impl FsUri {
34
35 pub fn to_json_string(&self) -> Result<String> {
37 serde_json::to_string(self).map_err(Into::into)
38 }
39
40 pub fn from_json_str(json: impl AsRef<str>) -> Result<Self> {
42 serde_json::from_str(json.as_ref()).map_err(Into::into)
43 }
44
45 pub fn from_uri(uri: impl Into<String>) -> Self {
46 FsUri {
47 uri: uri.into(),
48 document_top_tree_uri: None,
49 }
50 }
51
52 pub fn from_path(path: impl AsRef<std::path::Path>) -> Self {
63 Self {
64 uri: path_to_android_file_uri(path),
65 document_top_tree_uri: None,
66 }
67 }
68
69 pub fn to_path(&self) -> Option<std::path::PathBuf> {
72 if self.is_file_scheme() {
73 return Some(android_file_uri_to_path(&self.uri));
74 }
75 None
76 }
77
78 pub fn is_file_scheme(&self) -> bool {
80 self.uri.starts_with("file://")
81 }
82
83 pub fn is_content_scheme(&self) -> bool {
85 self.uri.starts_with("content://")
86 }
87}
88
89impl From<&std::path::Path> for FsUri {
90 fn from(path: &std::path::Path) -> Self {
91 Self::from_path(path)
92 }
93}
94
95impl From<&std::path::PathBuf> for FsUri {
96 fn from(path: &std::path::PathBuf) -> Self {
97 Self::from_path(path)
98 }
99}
100
101impl From<std::path::PathBuf> for FsUri {
102 fn from(path: std::path::PathBuf) -> Self {
103 Self::from_path(path)
104 }
105}
106
107impl From<tauri_plugin_fs::FilePath> for FsUri {
108 fn from(value: tauri_plugin_fs::FilePath) -> Self {
109 match value {
110 tauri_plugin_fs::FilePath::Url(url) => Self::from_uri(url),
111 tauri_plugin_fs::FilePath::Path(path) => Self::from_path(path),
112 }
113 }
114}
115
116impl From<FsUri> for tauri_plugin_fs::FilePath {
117 fn from(value: FsUri) -> Self {
118 type NeverErr<T> = std::result::Result<T, std::convert::Infallible>;
119 NeverErr::unwrap(value.uri.parse())
120 }
121}
122
123fn android_file_uri_to_path(uri: impl AsRef<str>) -> std::path::PathBuf {
124 let uri = uri.as_ref();
125 let path_part = uri.strip_prefix("file://").unwrap_or(uri);
126 let decoded = percent_encoding::percent_decode_str(path_part).decode_utf8_lossy();
127
128 std::path::PathBuf::from(decoded.as_ref())
129}
130
131fn path_to_android_file_uri(path: impl AsRef<std::path::Path>) -> String {
132 let encoded = path
133 .as_ref()
134 .to_string_lossy()
135 .split('/')
136 .map(|s| encode_android_uri_component(s))
137 .collect::<Vec<_>>()
138 .join("/");
139
140 format!("file://{}", encoded)
141}