refactor: pull filesystem calls out into a designated yazi_fs crate (#3013)

This commit is contained in:
三咲雅 misaki masa 2025-07-23 22:43:11 +08:00 committed by GitHub
parent 1f596a01fc
commit c2883f1e05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 354 additions and 145 deletions

View file

@ -10,6 +10,7 @@ repository = "https://github.com/sxyazi/yazi"
[dependencies]
yazi-config = { path = "../yazi-config", version = "25.6.11" }
yazi-fs = { path = "../yazi-fs", version = "25.6.11" }
yazi-macro = { path = "../yazi-macro", version = "25.6.11" }
yazi-shared = { path = "../yazi-shared", version = "25.6.11" }
yazi-term = { path = "../yazi-term", version = "25.6.11" }

View file

@ -1,9 +1,9 @@
use std::{env, fmt::Display, path::Path};
use std::{env, fmt::Display};
use anyhow::Result;
use ratatui::layout::Rect;
use tracing::warn;
use yazi_shared::env_exists;
use yazi_shared::{env_exists, url::Url};
use crate::{Emulator, SHOWN, TMUX, drivers};
@ -35,18 +35,18 @@ impl Display for Adapter {
}
impl Adapter {
pub async fn image_show(self, path: &Path, max: Rect) -> Result<Rect> {
pub async fn image_show(self, url: &Url, max: Rect) -> Result<Rect> {
if max.is_empty() {
return Ok(Rect::default());
}
match self {
Self::Kgp => drivers::Kgp::image_show(path, max).await,
Self::KgpOld => drivers::KgpOld::image_show(path, max).await,
Self::Iip => drivers::Iip::image_show(path, max).await,
Self::Sixel => drivers::Sixel::image_show(path, max).await,
Self::X11 | Self::Wayland => drivers::Ueberzug::image_show(path, max).await,
Self::Chafa => drivers::Chafa::image_show(path, max).await,
Self::Kgp => drivers::Kgp::image_show(url, max).await,
Self::KgpOld => drivers::KgpOld::image_show(url, max).await,
Self::Iip => drivers::Iip::image_show(url, max).await,
Self::Sixel => drivers::Sixel::image_show(url, max).await,
Self::X11 | Self::Wayland => drivers::Ueberzug::image_show(url, max).await,
Self::Chafa => drivers::Chafa::image_show(url, max).await,
}
}

View file

@ -1,4 +1,4 @@
use std::{fmt::Write, io::Write as ioWrite, path::Path};
use std::{fmt::Write, io::Write as ioWrite};
use anyhow::Result;
use base64::{Engine, engine::{Config, general_purpose::STANDARD}};
@ -6,14 +6,15 @@ use crossterm::{cursor::MoveTo, queue};
use image::{DynamicImage, ExtendedColorType, ImageEncoder, codecs::{jpeg::JpegEncoder, png::PngEncoder}};
use ratatui::layout::Rect;
use yazi_config::YAZI;
use yazi_shared::url::Url;
use crate::{CLOSE, Emulator, Image, START, adapter::Adapter};
pub(crate) struct Iip;
impl Iip {
pub(crate) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
let img = Image::downscale(path, max).await?;
pub(crate) async fn image_show(url: &Url, max: Rect) -> Result<Rect> {
let img = Image::downscale(url, max).await?;
let area = Image::pixel_area((img.width(), img.height()), max);
let b = Self::encode(img).await?;

View file

@ -1,11 +1,12 @@
use core::str;
use std::{io::Write, path::Path};
use std::io::Write;
use anyhow::Result;
use base64::{Engine, engine::general_purpose};
use crossterm::{cursor::MoveTo, queue};
use image::DynamicImage;
use ratatui::layout::Rect;
use yazi_shared::url::Url;
use crate::{CLOSE, ESCAPE, Emulator, START, adapter::Adapter, image::Image};
@ -312,8 +313,8 @@ static DIACRITICS: [char; 297] = [
pub(crate) struct Kgp;
impl Kgp {
pub(crate) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
let img = Image::downscale(path, max).await?;
pub(crate) async fn image_show(url: &Url, max: Rect) -> Result<Rect> {
let img = Image::downscale(url, max).await?;
let area = Image::pixel_area((img.width(), img.height()), max);
let b1 = Self::encode(img).await?;

View file

@ -1,10 +1,11 @@
use core::str;
use std::{io::Write, path::Path};
use std::io::Write;
use anyhow::Result;
use base64::{Engine, engine::general_purpose};
use image::DynamicImage;
use ratatui::layout::Rect;
use yazi_shared::url::Url;
use yazi_term::tty::TTY;
use crate::{CLOSE, ESCAPE, Emulator, Image, START, adapter::Adapter};
@ -12,8 +13,8 @@ use crate::{CLOSE, ESCAPE, Emulator, Image, START, adapter::Adapter};
pub(crate) struct KgpOld;
impl KgpOld {
pub(crate) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
let img = Image::downscale(path, max).await?;
pub(crate) async fn image_show(url: &Url, max: Rect) -> Result<Rect> {
let img = Image::downscale(url, max).await?;
let area = Image::pixel_area((img.width(), img.height()), max);
let b = Self::encode(img).await?;

View file

@ -1,4 +1,4 @@
use std::{io::Write, path::Path};
use std::io::Write;
use anyhow::{Result, bail};
use crossterm::{cursor::MoveTo, queue};
@ -6,14 +6,15 @@ use image::{DynamicImage, GenericImageView, RgbImage};
use palette::{Srgb, cast::ComponentsAs};
use quantette::{ColorSlice, PaletteSize, QuantizeOutput, wu::UIntBinner};
use ratatui::layout::Rect;
use yazi_shared::url::Url;
use crate::{CLOSE, ESCAPE, Emulator, Image, START, adapter::Adapter};
pub(crate) struct Sixel;
impl Sixel {
pub(crate) async fn image_show(path: &Path, max: Rect) -> Result<Rect> {
let img = Image::downscale(path, max).await?;
pub(crate) async fn image_show(url: &Url, max: Rect) -> Result<Rect> {
let img = Image::downscale(url, max).await?;
let area = Image::pixel_area((img.width(), img.height()), max);
let b = Self::encode(img).await?;

View file

@ -1,17 +1,19 @@
use std::path::Path;
use std::io::BufReader;
use anyhow::Result;
use image::{DynamicImage, ExtendedColorType, ImageDecoder, ImageEncoder, ImageError, ImageReader, ImageResult, Limits, codecs::{jpeg::JpegEncoder, png::PngEncoder}, imageops::FilterType, metadata::Orientation};
use image::{DynamicImage, ExtendedColorType, ImageDecoder, ImageEncoder, ImageError, ImageFormat, ImageReader, ImageResult, Limits, codecs::{jpeg::JpegEncoder, png::PngEncoder}, imageops::FilterType, metadata::Orientation};
use ratatui::layout::Rect;
use yazi_config::YAZI;
use yazi_fs::services;
use yazi_shared::url::Url;
use crate::Dimension;
pub struct Image;
impl Image {
pub async fn precache(path: &Path, cache: &Path) -> Result<()> {
let (mut img, orientation, icc) = Self::decode_from(path).await?;
pub async fn precache(src: &Url, cache: &Url) -> Result<()> {
let (mut img, orientation, icc) = Self::decode_from(src).await?;
let (w, h) = Self::flip_size(orientation, (YAZI.preview.max_width, YAZI.preview.max_height));
let buf = tokio::task::spawn_blocking(move || {
@ -38,11 +40,11 @@ impl Image {
})
.await??;
Ok(tokio::fs::write(cache, buf).await?)
Ok(services::write(cache, buf).await?)
}
pub(super) async fn downscale(path: &Path, rect: Rect) -> Result<DynamicImage> {
let (mut img, orientation, _) = Self::decode_from(path).await?;
pub(super) async fn downscale(url: &Url, rect: Rect) -> Result<DynamicImage> {
let (mut img, orientation, _) = Self::decode_from(url).await?;
let (w, h) = Self::flip_size(orientation, Self::max_pixel(rect));
// Fast path.
@ -96,7 +98,7 @@ impl Image {
}
}
async fn decode_from(path: &Path) -> ImageResult<(DynamicImage, Orientation, Option<Vec<u8>>)> {
async fn decode_from(url: &Url) -> ImageResult<(DynamicImage, Orientation, Option<Vec<u8>>)> {
let mut limits = Limits::no_limits();
if YAZI.tasks.image_alloc > 0 {
limits.max_alloc = Some(YAZI.tasks.image_alloc as u64);
@ -108,11 +110,13 @@ impl Image {
limits.max_image_height = Some(YAZI.tasks.image_bound[1] as u32);
}
let path = path.to_owned();
tokio::task::spawn_blocking(move || {
let mut reader = ImageReader::open(path)?;
reader.limits(limits);
let mut reader = ImageReader::new(BufReader::new(services::open(&url).await?.into_std().await));
if let Ok(format) = ImageFormat::from_path(url) {
reader.set_format(format);
}
reader.limits(limits);
tokio::task::spawn_blocking(move || {
let mut decoder = reader.with_guessed_format()?.into_decoder()?;
let orientation = decoder.orientation().unwrap_or(Orientation::NoTransforms);
let icc = decoder.icc_profile().unwrap_or_default();