#![allow(clippy::len_without_is_empty)]
use std::io::{Error, ErrorKind, Result};
use std::path::Path;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use web_sys::FileSystemFileHandle;
use crate::{get_directory, Entry, FileType};
#[derive(Debug)]
pub struct Metadata {
file_type: FileType,
size: u64,
last_modified: SystemTime,
}
impl Metadata {
pub(crate) async fn from_file_handle(handle: &FileSystemFileHandle) -> Result<Self> {
let file = crate::resolve::<web_sys::File>(handle.get_file()).await?;
let since_epoch = Duration::from_millis(file.last_modified() as u64);
let last_modified = UNIX_EPOCH + since_epoch;
let size = file.size() as u64;
Ok(Metadata {
file_type: FileType::File,
size,
last_modified,
})
}
}
impl Metadata {
pub fn file_type(&self) -> FileType {
self.file_type
}
pub fn is_dir(&self) -> bool {
self.file_type.is_dir()
}
pub fn is_file(&self) -> bool {
self.file_type.is_file()
}
pub fn is_symlink(&self) -> bool {
false
}
pub fn len(&self) -> u64 {
self.size
}
pub async fn accessed(&self) -> Result<SystemTime> {
Err(Error::new(ErrorKind::Unsupported, "unable to provide"))
}
pub fn created(&self) -> Result<SystemTime> {
Err(Error::new(ErrorKind::Unsupported, "unable to provide"))
}
pub fn modified(&self) -> Result<SystemTime> {
if self.is_file() {
Ok(self.last_modified)
} else {
Err(Error::new(ErrorKind::Unsupported, "unable to provide"))
}
}
pub fn permissions(&self) -> Permissions {
Permissions { readonly: false }
}
}
#[derive(Debug, Clone, Copy)]
pub struct Permissions {
readonly: bool,
}
impl Permissions {
pub fn readonly(&self) -> bool {
self.readonly
}
}
pub async fn metadata<P: AsRef<Path>>(path: P) -> Result<Metadata> {
let fpath = path.as_ref();
let parent = if let Some(parent) = fpath.parent() {
get_directory(parent).await?
} else {
crate::root_directory().await?
};
let Some(fname) = fpath.file_name() else {
return Err(Error::new(
ErrorKind::InvalidInput,
"unable to find directory name",
));
};
let entry = crate::Entry::from_directory(&parent, fname.to_string_lossy().as_ref()).await?;
match entry {
Entry::Directory(_) => Ok(Metadata {
file_type: FileType::Directory,
size: 0,
last_modified: SystemTime::UNIX_EPOCH,
}),
Entry::File(handle) => Metadata::from_file_handle(&handle).await,
}
}