(&self, path: &str)
| 136 | } |
| 137 | |
| 138 | pub async fn export(&self, path: &str) -> Result<(), String> { |
| 139 | #[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))] |
| 140 | { |
| 141 | let full_path = self.resolve_path(path)?; |
| 142 | let bytes = std::fs::read(&full_path).map_err(|e| e.to_string())?; |
| 143 | |
| 144 | let normalized_path = normalize_relative_path(path, "storage export path")?; |
| 145 | let file_name = normalized_path |
| 146 | .rsplit('/') |
| 147 | .next() |
| 148 | .filter(|s| !s.is_empty()) |
| 149 | .ok_or_else(|| "Invalid export file name".to_owned())?; |
| 150 | |
| 151 | let target_path = rfd::FileDialog::new() |
| 152 | .set_file_name(file_name) |
| 153 | .save_file() |
| 154 | .ok_or_else(|| "Export canceled".to_owned())?; |
| 155 | |
| 156 | std::fs::write(target_path, bytes).map_err(|e| e.to_string())?; |
| 157 | Ok(()) |
| 158 | } |
| 159 | |
| 160 | #[cfg(target_os = "android")] |
| 161 | { |
| 162 | let full_path = self.resolve_path(path)?; |
| 163 | std::fs::metadata(&full_path).map_err(|e| e.to_string())?; |
| 164 | |
| 165 | let normalized_path = normalize_relative_path(path, "storage export path")?; |
| 166 | let file_name = normalized_path |
| 167 | .rsplit('/') |
| 168 | .next() |
| 169 | .filter(|s| !s.is_empty()) |
| 170 | .ok_or_else(|| "Invalid export file name".to_owned())?; |
| 171 | |
| 172 | let full_path_string = full_path.to_string_lossy().into_owned(); |
| 173 | let source_path_c = |
| 174 | std::ffi::CString::new(full_path_string).map_err(|_| { |
| 175 | "Export path contains unsupported NUL byte".to_owned() |
| 176 | })?; |
| 177 | let file_name_c = std::ffi::CString::new(file_name).map_err(|_| { |
| 178 | "Export file name contains unsupported NUL byte".to_owned() |
| 179 | })?; |
| 180 | let mime_type_c = std::ffi::CString::new(guess_mime_type(&normalized_path)) |
| 181 | .map_err(|_| "Export MIME type contains unsupported NUL byte".to_owned())?; |
| 182 | |
| 183 | unsafe { |
| 184 | let env = macroquad::miniquad::native::android::attach_jni_env(); |
| 185 | let activity = macroquad::miniquad::native::android::ACTIVITY; |
| 186 | if activity.is_null() { |
| 187 | return Err("Android activity is not available".to_owned()); |
| 188 | } |
| 189 | |
| 190 | let get_object_class = (**env).GetObjectClass.unwrap(); |
| 191 | let get_method_id = (**env).GetMethodID.unwrap(); |
| 192 | let call_void_method = (**env).CallVoidMethod.unwrap(); |
| 193 | let new_string_utf = (**env).NewStringUTF.unwrap(); |
| 194 | let delete_local_ref = (**env).DeleteLocalRef.unwrap(); |
| 195 | let exception_check = (**env).ExceptionCheck.unwrap(); |
nothing calls this directly
no test coverage detected