use super::Result;
use crate::{plugin::PluginHandle, Runtime};
use std::path::{Path, PathBuf};
pub struct PathResolver<R: Runtime>(pub(crate) PluginHandle<R>);
impl<R: Runtime> Clone for PathResolver<R> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
#[derive(serde::Deserialize)]
struct PathResponse {
path: PathBuf,
}
#[derive(serde::Serialize)]
struct GetFileNameFromUriRequest<'a> {
uri: &'a str,
}
#[derive(serde::Deserialize)]
struct GetFileNameFromUriResponse {
name: Option<String>,
}
impl<R: Runtime> PathResolver<R> {
pub fn file_name(&self, path: &str) -> Option<String> {
if path.starts_with("content://") || path.starts_with("file://") {
self
.0
.run_mobile_plugin::<GetFileNameFromUriResponse>(
"getFileNameFromUri",
GetFileNameFromUriRequest { uri: path },
)
.map(|r| r.name)
.unwrap_or_else(|e| {
log::error!("failed to get file name from URI: {e}");
None
})
} else {
Path::new(path)
.file_name()
.map(|name| name.to_string_lossy().into_owned())
}
}
fn call_resolve(&self, dir: &str) -> Result<PathBuf> {
self
.0
.run_mobile_plugin::<PathResponse>(dir, ())
.map(|r| r.path)
.map_err(Into::into)
}
pub fn audio_dir(&self) -> Result<PathBuf> {
self.call_resolve("getAudioDir")
}
pub fn cache_dir(&self) -> Result<PathBuf> {
self.call_resolve("getExternalCacheDir")
}
pub fn config_dir(&self) -> Result<PathBuf> {
self.call_resolve("getConfigDir")
}
pub fn data_dir(&self) -> Result<PathBuf> {
self.call_resolve("getDataDir")
}
pub fn local_data_dir(&self) -> Result<PathBuf> {
self.call_resolve("getDataDir")
}
pub fn document_dir(&self) -> Result<PathBuf> {
self.call_resolve("getDocumentDir")
}
pub fn download_dir(&self) -> Result<PathBuf> {
self.call_resolve("getDownloadDir")
}
pub fn picture_dir(&self) -> Result<PathBuf> {
self.call_resolve("getPictureDir")
}
pub fn public_dir(&self) -> Result<PathBuf> {
self.call_resolve("getPublicDir")
}
pub fn video_dir(&self) -> Result<PathBuf> {
self.call_resolve("getVideoDir")
}
pub fn resource_dir(&self) -> Result<PathBuf> {
self.call_resolve("getResourcesDir")
}
pub fn app_config_dir(&self) -> Result<PathBuf> {
self.call_resolve("getConfigDir")
}
pub fn app_data_dir(&self) -> Result<PathBuf> {
self.call_resolve("getDataDir")
}
pub fn app_local_data_dir(&self) -> Result<PathBuf> {
self.call_resolve("getDataDir")
}
pub fn app_cache_dir(&self) -> Result<PathBuf> {
self.call_resolve("getCacheDir")
}
pub fn app_log_dir(&self) -> Result<PathBuf> {
self
.call_resolve("getConfigDir")
.map(|dir| dir.join("logs"))
}
pub fn temp_dir(&self) -> Result<PathBuf> {
Ok(std::env::temp_dir())
}
pub fn home_dir(&self) -> Result<PathBuf> {
self.call_resolve("getHomeDir")
}
}