luby/crates/lb/src/fs/async.rs
2025-06-30 19:23:44 +10:00

84 lines
2.1 KiB
Rust

use super::*;
use luaffi::{cdef, metatype};
use std::cell::RefCell;
use tokio::fs::{DirEntry, ReadDir};
/// Iterator over the entries in a directory.
#[derive(Debug)]
#[cdef]
pub struct lb_read_dir(#[opaque] RefCell<ReadDir>);
#[metatype]
impl lb_read_dir {
pub(super) fn new(iter: ReadDir) -> Self {
Self(RefCell::new(iter))
}
/// Returns the next entry in the directory, or `nil` if there are no more entries.
///
/// # Errors
///
/// This function may throw if the directory could not be read.
#[call]
pub async extern "Lua-C" fn next(&self) -> Result<Option<lb_dir_entry>> {
Ok(self
.0
.try_borrow_mut()?
.next_entry()
.await?
.map(lb_dir_entry::new))
}
}
/// Entry inside of a directory on the filesystem.
#[derive(Debug)]
#[cdef]
pub struct lb_dir_entry(#[opaque] DirEntry);
#[metatype]
impl lb_dir_entry {
pub(super) fn new(entry: DirEntry) -> Self {
Self(entry)
}
/// Returns the full path of this entry.
pub extern "Lua-C" fn path(&self) -> String {
self.0.path().to_string_lossy().into()
}
/// Returns the file name of this entry.
pub extern "Lua-C" fn name(&self) -> String {
self.0.file_name().to_string_lossy().into()
}
/// Returns the type of this entry.
///
/// # Errors
///
/// This function may throw if the file type could not be determined.
pub async extern "Lua-C" fn r#type(&self) -> Result<lb_file_type> {
Ok(lb_file_type::new(self.0.file_type().await?))
}
/// Returns the metadata for this entry.
///
/// # Errors
///
/// This function may throw if the metadata could not be retrieved.
pub async extern "Lua-C" fn metadata(&self) -> Result<lb_file_meta> {
Ok(lb_file_meta::new(self.0.metadata().await?))
}
/// Returns the inode number for this entry.
#[cfg(unix)]
pub extern "Lua-C" fn ino(&self) -> u64 {
self.0.ino()
}
/// Returns the full path of this entry.
#[tostring]
pub extern "Lua" fn tostring(&self) -> String {
self.path()
}
}