feat: new fs.calc_size() API

This commit is contained in:
sxyazi 2025-04-28 21:41:28 +08:00
parent 6a9e7da8a3
commit 19b484a744
No known key found for this signature in database
5 changed files with 34 additions and 7 deletions

View file

@ -13,7 +13,12 @@ pub enum SizeCalculator {
impl SizeCalculator { impl SizeCalculator {
pub async fn new(path: impl AsRef<Path>) -> std::io::Result<Self> { pub async fn new(path: impl AsRef<Path>) -> std::io::Result<Self> {
let p = path.as_ref().to_owned(); let p = path.as_ref().to_owned();
tokio::task::spawn_blocking(|| { tokio::task::spawn_blocking(move || {
let meta = std::fs::symlink_metadata(&p)?;
if !meta.is_dir() {
return Ok(Self::Idle((VecDeque::new(), Some(meta.len()))));
}
let mut buf = VecDeque::from([Either::Right(std::fs::read_dir(p)?)]); let mut buf = VecDeque::from([Either::Right(std::fs::read_dir(p)?)]);
let size = Self::next_chunk(&mut buf); let size = Self::next_chunk(&mut buf);
Ok(Self::Idle((buf, size))) Ok(Self::Idle((buf, size)))
@ -87,8 +92,8 @@ impl SizeCalculator {
let Ok(ft) = ent.file_type() else { continue }; let Ok(ft) = ent.file_type() else { continue };
if ft.is_dir() { if ft.is_dir() {
buf.push_back(Either::Left(ent.path())); buf.push_back(Either::Left(ent.path()));
} else { } else if let Ok(meta) = ent.metadata() {
size += ent.metadata().map(|m| m.len()).unwrap_or(0); size += meta.len();
} }
} }
Some(size) Some(size)

View file

@ -1,3 +1,3 @@
#![allow(clippy::module_inception)] #![allow(clippy::module_inception)]
yazi_macro::mod_flat!(cha chan icon image input layer mouse permit range); yazi_macro::mod_flat!(cha chan icon image input layer mouse permit range receiver);

View file

View file

@ -1,8 +1,8 @@
use globset::GlobBuilder; use globset::GlobBuilder;
use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, Table, Value}; use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua, Table, UserData, UserDataMethods, Value};
use tokio::fs; use tokio::fs;
use yazi_binding::{Error, Url, UrlRef}; use yazi_binding::{Error, Url, UrlRef};
use yazi_fs::{mounts::PARTITIONS, remove_dir_clean}; use yazi_fs::{SizeCalculator, mounts::PARTITIONS, remove_dir_clean};
use crate::{Composer, bindings::Cha, file::File}; use crate::{Composer, bindings::Cha, file::File};
@ -16,6 +16,7 @@ pub fn compose(lua: &Lua) -> mlua::Result<Value> {
b"create" => create(lua)?, b"create" => create(lua)?,
b"remove" => remove(lua)?, b"remove" => remove(lua)?,
b"read_dir" => read_dir(lua)?, b"read_dir" => read_dir(lua)?,
b"calc_size" => calc_size(lua)?,
b"expand_url" => expand_url(lua)?, b"expand_url" => expand_url(lua)?,
b"unique_name" => unique_name(lua)?, b"unique_name" => unique_name(lua)?,
b"partitions" => partitions(lua)?, b"partitions" => partitions(lua)?,
@ -152,6 +153,27 @@ fn read_dir(lua: &Lua) -> mlua::Result<Function> {
}) })
} }
fn calc_size(lua: &Lua) -> mlua::Result<Function> {
lua.create_async_function(|lua, url: UrlRef| async move {
struct Wrapper(SizeCalculator);
impl UserData for Wrapper {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_async_method_mut("recv", |lua, mut me, ()| async move {
match me.0.next().await {
Ok(value) => (value, Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
});
}
}
match SizeCalculator::new(&*url).await {
Ok(it) => Wrapper(it).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
})
}
fn expand_url(lua: &Lua) -> mlua::Result<Function> { fn expand_url(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|_, value: Value| { lua.create_function(|_, value: Value| {
use yazi_fs::expand_path; use yazi_fs::expand_path;

View file

@ -73,7 +73,7 @@ impl Prework {
self.prog.send(TaskProg::Adv(task.id, 1, 0))?; self.prog.send(TaskProg::Adv(task.id, 1, 0))?;
} }
PreworkOp::Size(task) => { PreworkOp::Size(task) => {
let length = SizeCalculator::total(&task.target).await?; let length = SizeCalculator::total(&task.target).await.unwrap_or(0);
task.throttle.done((task.target, length), |buf| { task.throttle.done((task.target, length), |buf| {
{ {
let mut loading = self.size_loading.write(); let mut loading = self.size_loading.write();