mirror of
https://github.com/sxyazi/yazi.git
synced 2024-11-27 14:03:29 +03:00
refactor: prefer FromStr
over Default
for configuration parsing with side effects
This commit is contained in:
parent
2a35d30f38
commit
f35712a768
72
Cargo.lock
generated
72
Cargo.lock
generated
@ -218,6 +218,15 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block2"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
|
||||||
|
dependencies = [
|
||||||
|
"objc2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
@ -970,9 +979,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "imagesize"
|
name = "imagesize"
|
||||||
version = "0.12.0"
|
version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
|
checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
@ -1150,15 +1159,6 @@ dependencies = [
|
|||||||
"which",
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "malloc_buf"
|
|
||||||
version = "0.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md-5"
|
name = "md-5"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@ -1328,12 +1328,37 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc"
|
name = "objc-sys"
|
||||||
version = "0.2.7"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"malloc_buf",
|
"objc-sys",
|
||||||
|
"objc2-encode",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-encode"
|
||||||
|
version = "4.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "objc2-foundation"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"block2",
|
||||||
|
"libc",
|
||||||
|
"objc2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2210,17 +2235,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trash"
|
name = "trash"
|
||||||
version = "4.1.1"
|
version = "5.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c254b119cf49bdde3dfef21b1dc492dc8026b75566ca24aa77993eccd7cbc1b5"
|
checksum = "8d8fbfb70b1fad5c0b788f9b2e1bf4d04e5ac6efa828f1ed9ee462c50ff9cf05"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"objc",
|
"objc2",
|
||||||
|
"objc2-foundation",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
"url",
|
"urlencoding",
|
||||||
"windows",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2284,6 +2310,12 @@ dependencies = [
|
|||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlencoding"
|
||||||
|
version = "2.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -2758,7 +2790,6 @@ dependencies = [
|
|||||||
"indexmap",
|
"indexmap",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
"serde",
|
"serde",
|
||||||
"shell-words",
|
|
||||||
"toml",
|
"toml",
|
||||||
"validator",
|
"validator",
|
||||||
"yazi-shared",
|
"yazi-shared",
|
||||||
@ -2934,7 +2965,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"shell-words",
|
"shell-words",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -13,15 +13,15 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
|
|||||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
ansi-to-tui = "3.1.0"
|
ansi-to-tui = "=3.1.0"
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
arc-swap = "1.7.1"
|
arc-swap = "1.7.1"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
color_quant = "1.1.0"
|
color_quant = "1.1.0"
|
||||||
crossterm = "0.27.0"
|
crossterm = "0.27.0"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
image = "0.24.9"
|
image = "=0.24.9"
|
||||||
imagesize = "0.12.0"
|
imagesize = "0.13.0"
|
||||||
kamadak-exif = "0.5.5"
|
kamadak-exif = "0.5.5"
|
||||||
ratatui = "0.26.3"
|
ratatui = "0.26.3"
|
||||||
scopeguard = "1.2.0"
|
scopeguard = "1.2.0"
|
||||||
|
@ -37,6 +37,10 @@ impl Display for Adapter {
|
|||||||
|
|
||||||
impl Adapter {
|
impl Adapter {
|
||||||
pub async fn image_show(self, path: &Path, max: Rect) -> Result<Rect> {
|
pub async fn image_show(self, path: &Path, max: Rect) -> Result<Rect> {
|
||||||
|
if max.is_empty() {
|
||||||
|
return Ok(Rect::default());
|
||||||
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Self::Kitty => Kitty::image_show(path, max).await,
|
Self::Kitty => Kitty::image_show(path, max).await,
|
||||||
Self::KittyOld => KittyOld::image_show(path, max).await,
|
Self::KittyOld => KittyOld::image_show(path, max).await,
|
||||||
|
@ -20,6 +20,5 @@ globset = "0.4.14"
|
|||||||
indexmap = "2.2.6"
|
indexmap = "2.2.6"
|
||||||
ratatui = "0.26.3"
|
ratatui = "0.26.3"
|
||||||
serde = { version = "1.0.203", features = [ "derive" ] }
|
serde = { version = "1.0.203", features = [ "derive" ] }
|
||||||
shell-words = "1.1.0"
|
|
||||||
toml = { version = "0.8.14", features = [ "preserve_order" ] }
|
toml = { version = "0.8.14", features = [ "preserve_order" ] }
|
||||||
validator = { version = "0.18.1", features = [ "derive" ] }
|
validator = { version = "0.18.1", features = [ "derive" ] }
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use yazi_shared::Layer;
|
use yazi_shared::Layer;
|
||||||
|
|
||||||
use super::Control;
|
use super::Control;
|
||||||
use crate::{Preset, MERGED_KEYMAP};
|
use crate::Preset;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Keymap {
|
pub struct Keymap {
|
||||||
@ -14,6 +16,28 @@ pub struct Keymap {
|
|||||||
pub completion: Vec<Control>,
|
pub completion: Vec<Control>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Keymap {
|
||||||
|
#[inline]
|
||||||
|
pub fn get(&self, layer: Layer) -> &Vec<Control> {
|
||||||
|
match layer {
|
||||||
|
Layer::App => unreachable!(),
|
||||||
|
Layer::Manager => &self.manager,
|
||||||
|
Layer::Tasks => &self.tasks,
|
||||||
|
Layer::Select => &self.select,
|
||||||
|
Layer::Input => &self.input,
|
||||||
|
Layer::Help => &self.help,
|
||||||
|
Layer::Completion => &self.completion,
|
||||||
|
Layer::Which => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Keymap {
|
||||||
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> { toml::from_str(s) }
|
||||||
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Keymap {
|
impl<'de> Deserialize<'de> for Keymap {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
@ -62,23 +86,3 @@ impl<'de> Deserialize<'de> for Keymap {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Keymap {
|
|
||||||
fn default() -> Self { toml::from_str(&MERGED_KEYMAP).unwrap() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Keymap {
|
|
||||||
#[inline]
|
|
||||||
pub fn get(&self, layer: Layer) -> &Vec<Control> {
|
|
||||||
match layer {
|
|
||||||
Layer::App => unreachable!(),
|
|
||||||
Layer::Manager => &self.manager,
|
|
||||||
Layer::Tasks => &self.tasks,
|
|
||||||
Layer::Select => &self.select,
|
|
||||||
Layer::Input => &self.input,
|
|
||||||
Layer::Help => &self.help,
|
|
||||||
Layer::Completion => &self.completion,
|
|
||||||
Layer::Which => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#![allow(clippy::module_inception)]
|
#![allow(clippy::module_inception)]
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use yazi_shared::{RoCell, Xdg};
|
use yazi_shared::{RoCell, Xdg};
|
||||||
|
|
||||||
pub mod keymap;
|
pub mod keymap;
|
||||||
@ -15,7 +17,6 @@ pub mod preview;
|
|||||||
mod priority;
|
mod priority;
|
||||||
mod tasks;
|
mod tasks;
|
||||||
pub mod theme;
|
pub mod theme;
|
||||||
mod validation;
|
|
||||||
pub mod which;
|
pub mod which;
|
||||||
|
|
||||||
pub use layout::*;
|
pub use layout::*;
|
||||||
@ -23,10 +24,6 @@ pub(crate) use pattern::*;
|
|||||||
pub(crate) use preset::*;
|
pub(crate) use preset::*;
|
||||||
pub use priority::*;
|
pub use priority::*;
|
||||||
|
|
||||||
static MERGED_YAZI: RoCell<String> = RoCell::new();
|
|
||||||
static MERGED_KEYMAP: RoCell<String> = RoCell::new();
|
|
||||||
static MERGED_THEME: RoCell<String> = RoCell::new();
|
|
||||||
|
|
||||||
pub static LAYOUT: RoCell<arc_swap::ArcSwap<Layout>> = RoCell::new();
|
pub static LAYOUT: RoCell<arc_swap::ArcSwap<Layout>> = RoCell::new();
|
||||||
|
|
||||||
pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new();
|
pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new();
|
||||||
@ -43,23 +40,23 @@ pub static WHICH: RoCell<which::Which> = RoCell::new();
|
|||||||
|
|
||||||
pub fn init() -> anyhow::Result<()> {
|
pub fn init() -> anyhow::Result<()> {
|
||||||
let config_dir = Xdg::config_dir();
|
let config_dir = Xdg::config_dir();
|
||||||
MERGED_YAZI.init(Preset::yazi(&config_dir)?);
|
let yazi_toml = &Preset::yazi(&config_dir)?;
|
||||||
MERGED_KEYMAP.init(Preset::keymap(&config_dir)?);
|
let keymap_toml = &Preset::keymap(&config_dir)?;
|
||||||
MERGED_THEME.init(Preset::theme(&config_dir)?);
|
let theme_toml = &Preset::theme(&config_dir)?;
|
||||||
|
|
||||||
LAYOUT.with(Default::default);
|
LAYOUT.with(Default::default);
|
||||||
|
|
||||||
KEYMAP.with(Default::default);
|
KEYMAP.init(<_>::from_str(keymap_toml)?);
|
||||||
LOG.with(Default::default);
|
LOG.init(<_>::from_str(yazi_toml)?);
|
||||||
MANAGER.with(Default::default);
|
MANAGER.init(<_>::from_str(yazi_toml)?);
|
||||||
OPEN.with(Default::default);
|
OPEN.init(<_>::from_str(yazi_toml)?);
|
||||||
PLUGIN.with(Default::default);
|
PLUGIN.init(<_>::from_str(yazi_toml)?);
|
||||||
PREVIEW.with(Default::default);
|
PREVIEW.init(<_>::from_str(yazi_toml)?);
|
||||||
TASKS.with(Default::default);
|
TASKS.init(<_>::from_str(yazi_toml)?);
|
||||||
THEME.with(Default::default);
|
THEME.init(<_>::from_str(theme_toml)?);
|
||||||
INPUT.with(Default::default);
|
INPUT.init(<_>::from_str(yazi_toml)?);
|
||||||
SELECT.with(Default::default);
|
SELECT.init(<_>::from_str(yazi_toml)?);
|
||||||
WHICH.with(Default::default);
|
WHICH.init(<_>::from_str(yazi_toml)?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
use serde::{Deserialize, Deserializer};
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::MERGED_YAZI;
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Log {
|
pub struct Log {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Log {
|
impl FromStr for Log {
|
||||||
fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> { toml::from_str(s) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Log {
|
impl<'de> Deserialize<'de> for Log {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use super::{ManagerRatio, MouseEvents, SortBy};
|
use super::{ManagerRatio, MouseEvents, SortBy};
|
||||||
use crate::{validation::check_validation, MERGED_YAZI};
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Validate)]
|
#[derive(Debug, Deserialize, Serialize, Validate)]
|
||||||
pub struct Manager {
|
pub struct Manager {
|
||||||
@ -24,16 +25,18 @@ pub struct Manager {
|
|||||||
pub mouse_events: MouseEvents,
|
pub mouse_events: MouseEvents,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Manager {
|
impl FromStr for Manager {
|
||||||
fn default() -> Self {
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
manager: Manager,
|
manager: Manager,
|
||||||
}
|
}
|
||||||
|
|
||||||
let manager = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().manager;
|
let manager = toml::from_str::<Outer>(s)?.manager;
|
||||||
|
manager.validate()?;
|
||||||
|
|
||||||
check_validation(manager.validate());
|
Ok(manager)
|
||||||
manager
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MouseEvents {
|
impl MouseEvents {
|
||||||
#[inline]
|
|
||||||
pub const fn draggable(self) -> bool { self.contains(Self::DRAG) }
|
pub const fn draggable(self) -> bool { self.contains(Self::DRAG) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
use std::{collections::HashMap, path::Path};
|
use std::{collections::HashMap, path::Path, str::FromStr};
|
||||||
|
|
||||||
use indexmap::IndexSet;
|
use indexmap::IndexSet;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use yazi_shared::MIME_DIR;
|
use yazi_shared::MIME_DIR;
|
||||||
|
|
||||||
use super::Opener;
|
use super::Opener;
|
||||||
use crate::{open::OpenRule, Preset, MERGED_YAZI};
|
use crate::{open::OpenRule, Preset};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Open {
|
pub struct Open {
|
||||||
@ -13,10 +13,6 @@ pub struct Open {
|
|||||||
openers: HashMap<String, IndexSet<Opener>>,
|
openers: HashMap<String, IndexSet<Opener>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Open {
|
|
||||||
fn default() -> Self { toml::from_str(&MERGED_YAZI).unwrap() }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Open {
|
impl Open {
|
||||||
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<IndexSet<&Opener>>
|
pub fn openers<P, M>(&self, path: P, mime: M) -> Option<IndexSet<&Opener>>
|
||||||
where
|
where
|
||||||
@ -58,6 +54,12 @@ impl Open {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for Open {
|
||||||
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> { toml::from_str(s) }
|
||||||
|
}
|
||||||
|
|
||||||
impl<'de> Deserialize<'de> for Open {
|
impl<'de> Deserialize<'de> for Open {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where
|
where
|
||||||
|
@ -6,7 +6,9 @@ use crate::{Pattern, Priority};
|
|||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Fetcher {
|
pub struct Fetcher {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub id: u8,
|
pub idx: u8,
|
||||||
|
|
||||||
|
pub id: String,
|
||||||
pub cond: Option<Condition>,
|
pub cond: Option<Condition>,
|
||||||
pub name: Option<Pattern>,
|
pub name: Option<Pattern>,
|
||||||
pub mime: Option<Pattern>,
|
pub mime: Option<Pattern>,
|
||||||
@ -24,6 +26,6 @@ pub struct FetcherProps {
|
|||||||
|
|
||||||
impl From<&Fetcher> for FetcherProps {
|
impl From<&Fetcher> for FetcherProps {
|
||||||
fn from(fetcher: &Fetcher) -> Self {
|
fn from(fetcher: &Fetcher) -> Self {
|
||||||
Self { id: fetcher.id, name: fetcher.run.name.to_owned(), prio: fetcher.prio }
|
Self { id: fetcher.idx, name: fetcher.run.name.to_owned(), prio: fetcher.prio }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use std::path::Path;
|
use std::{path::Path, str::FromStr};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use yazi_shared::MIME_DIR;
|
use yazi_shared::MIME_DIR;
|
||||||
|
|
||||||
use super::{Fetcher, Preloader, Previewer};
|
use super::{Fetcher, Preloader, Previewer};
|
||||||
use crate::{plugin::MAX_PREWORKERS, Preset, MERGED_YAZI};
|
use crate::{plugin::MAX_PREWORKERS, Preset};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Plugin {
|
pub struct Plugin {
|
||||||
@ -13,65 +13,6 @@ pub struct Plugin {
|
|||||||
pub previewers: Vec<Previewer>,
|
pub previewers: Vec<Previewer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Plugin {
|
|
||||||
fn default() -> Self {
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct Outer {
|
|
||||||
plugin: Shadow,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct Shadow {
|
|
||||||
fetchers: Vec<Fetcher>,
|
|
||||||
#[serde(default)]
|
|
||||||
prepend_fetchers: Vec<Fetcher>,
|
|
||||||
#[serde(default)]
|
|
||||||
append_fetchers: Vec<Fetcher>,
|
|
||||||
|
|
||||||
preloaders: Vec<Preloader>,
|
|
||||||
#[serde(default)]
|
|
||||||
prepend_preloaders: Vec<Preloader>,
|
|
||||||
#[serde(default)]
|
|
||||||
append_preloaders: Vec<Preloader>,
|
|
||||||
|
|
||||||
previewers: Vec<Previewer>,
|
|
||||||
#[serde(default)]
|
|
||||||
prepend_previewers: Vec<Previewer>,
|
|
||||||
#[serde(default)]
|
|
||||||
append_previewers: Vec<Previewer>,
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut shadow = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().plugin;
|
|
||||||
if shadow.append_previewers.iter().any(|r| r.any_file()) {
|
|
||||||
shadow.previewers.retain(|r| !r.any_file());
|
|
||||||
}
|
|
||||||
if shadow.append_previewers.iter().any(|r| r.any_dir()) {
|
|
||||||
shadow.previewers.retain(|r| !r.any_dir());
|
|
||||||
}
|
|
||||||
|
|
||||||
Preset::mix(&mut shadow.fetchers, shadow.prepend_fetchers, shadow.append_fetchers);
|
|
||||||
Preset::mix(&mut shadow.preloaders, shadow.prepend_preloaders, shadow.append_preloaders);
|
|
||||||
Preset::mix(&mut shadow.previewers, shadow.prepend_previewers, shadow.append_previewers);
|
|
||||||
|
|
||||||
if shadow.fetchers.len() + shadow.preloaders.len() > MAX_PREWORKERS as usize {
|
|
||||||
panic!("Fetchers and preloaders exceed the limit of {MAX_PREWORKERS}");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, p) in shadow.fetchers.iter_mut().enumerate() {
|
|
||||||
p.id = i as u8;
|
|
||||||
}
|
|
||||||
for (i, p) in shadow.preloaders.iter_mut().enumerate() {
|
|
||||||
p.id = shadow.fetchers.len() as u8 + i as u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
|
||||||
fetchers: shadow.fetchers,
|
|
||||||
preloaders: shadow.preloaders,
|
|
||||||
previewers: shadow.previewers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Plugin {
|
impl Plugin {
|
||||||
pub fn fetchers(
|
pub fn fetchers(
|
||||||
&self,
|
&self,
|
||||||
@ -118,3 +59,63 @@ impl Plugin {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl FromStr for Plugin {
|
||||||
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Outer {
|
||||||
|
plugin: Shadow,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Shadow {
|
||||||
|
fetchers: Vec<Fetcher>,
|
||||||
|
#[serde(default)]
|
||||||
|
prepend_fetchers: Vec<Fetcher>,
|
||||||
|
#[serde(default)]
|
||||||
|
append_fetchers: Vec<Fetcher>,
|
||||||
|
|
||||||
|
preloaders: Vec<Preloader>,
|
||||||
|
#[serde(default)]
|
||||||
|
prepend_preloaders: Vec<Preloader>,
|
||||||
|
#[serde(default)]
|
||||||
|
append_preloaders: Vec<Preloader>,
|
||||||
|
|
||||||
|
previewers: Vec<Previewer>,
|
||||||
|
#[serde(default)]
|
||||||
|
prepend_previewers: Vec<Previewer>,
|
||||||
|
#[serde(default)]
|
||||||
|
append_previewers: Vec<Previewer>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut shadow = toml::from_str::<Outer>(s)?.plugin;
|
||||||
|
if shadow.append_previewers.iter().any(|r| r.any_file()) {
|
||||||
|
shadow.previewers.retain(|r| !r.any_file());
|
||||||
|
}
|
||||||
|
if shadow.append_previewers.iter().any(|r| r.any_dir()) {
|
||||||
|
shadow.previewers.retain(|r| !r.any_dir());
|
||||||
|
}
|
||||||
|
|
||||||
|
Preset::mix(&mut shadow.fetchers, shadow.prepend_fetchers, shadow.append_fetchers);
|
||||||
|
Preset::mix(&mut shadow.preloaders, shadow.prepend_preloaders, shadow.append_preloaders);
|
||||||
|
Preset::mix(&mut shadow.previewers, shadow.prepend_previewers, shadow.append_previewers);
|
||||||
|
|
||||||
|
if shadow.fetchers.len() + shadow.preloaders.len() > MAX_PREWORKERS as usize {
|
||||||
|
panic!("Fetchers and preloaders exceed the limit of {MAX_PREWORKERS}");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, p) in shadow.fetchers.iter_mut().enumerate() {
|
||||||
|
p.idx = i as u8;
|
||||||
|
}
|
||||||
|
for (i, p) in shadow.preloaders.iter_mut().enumerate() {
|
||||||
|
p.idx = shadow.fetchers.len() as u8 + i as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
fetchers: shadow.fetchers,
|
||||||
|
preloaders: shadow.preloaders,
|
||||||
|
previewers: shadow.previewers,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,7 +6,8 @@ use crate::{Pattern, Priority};
|
|||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Preloader {
|
pub struct Preloader {
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub id: u8,
|
pub idx: u8,
|
||||||
|
|
||||||
pub name: Option<Pattern>,
|
pub name: Option<Pattern>,
|
||||||
pub mime: Option<Pattern>,
|
pub mime: Option<Pattern>,
|
||||||
pub run: Cmd,
|
pub run: Cmd,
|
||||||
@ -25,6 +26,6 @@ pub struct PreloaderProps {
|
|||||||
|
|
||||||
impl From<&Preloader> for PreloaderProps {
|
impl From<&Preloader> for PreloaderProps {
|
||||||
fn from(preloader: &Preloader) -> Self {
|
fn from(preloader: &Preloader) -> Self {
|
||||||
Self { id: preloader.id, name: preloader.run.name.to_owned(), prio: preloader.prio }
|
Self { id: preloader.idx, name: preloader.run.name.to_owned(), prio: preloader.prio }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use super::{Offset, Origin};
|
use super::{Offset, Origin};
|
||||||
use crate::MERGED_YAZI;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
@ -63,18 +64,19 @@ pub struct Input {
|
|||||||
pub quit_offset: Offset,
|
pub quit_offset: Offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Input {
|
impl Input {
|
||||||
fn default() -> Self {
|
pub const fn border(&self) -> u16 { 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Input {
|
||||||
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
input: Input,
|
input: Input,
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::from_str::<Outer>(&MERGED_YAZI).unwrap().input
|
Ok(toml::from_str::<Outer>(s)?.input)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
|
||||||
#[inline]
|
|
||||||
pub const fn border(&self) -> u16 { 2 }
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use super::{Offset, Origin};
|
use super::{Offset, Origin};
|
||||||
use crate::MERGED_YAZI;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Select {
|
pub struct Select {
|
||||||
@ -11,18 +12,19 @@ pub struct Select {
|
|||||||
pub open_offset: Offset,
|
pub open_offset: Offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Select {
|
impl Select {
|
||||||
fn default() -> Self {
|
pub const fn border(&self) -> u16 { 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Select {
|
||||||
|
type Err = toml::de::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
select: Select,
|
select: Select,
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::from_str::<Outer>(&MERGED_YAZI).unwrap().select
|
Ok(toml::from_str::<Outer>(s)?.select)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Select {
|
|
||||||
#[inline]
|
|
||||||
pub const fn border(&self) -> u16 { 2 }
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{mem, path::{Path, PathBuf}};
|
use std::{borrow::Cow, mem, path::{Path, PathBuf}};
|
||||||
|
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use toml::{Table, Value};
|
use toml::{Table, Value};
|
||||||
@ -8,17 +8,17 @@ use crate::theme::Flavor;
|
|||||||
pub(crate) struct Preset;
|
pub(crate) struct Preset;
|
||||||
|
|
||||||
impl Preset {
|
impl Preset {
|
||||||
pub(crate) fn yazi(p: &Path) -> Result<String> {
|
pub(crate) fn yazi(p: &Path) -> Result<Cow<str>> {
|
||||||
Self::merge_path(p.join("yazi.toml"), include_str!("../preset/yazi.toml"))
|
Self::merge_path(p.join("yazi.toml"), include_str!("../preset/yazi.toml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn keymap(p: &Path) -> Result<String> {
|
pub(crate) fn keymap(p: &Path) -> Result<Cow<str>> {
|
||||||
Self::merge_path(p.join("keymap.toml"), include_str!("../preset/keymap.toml"))
|
Self::merge_path(p.join("keymap.toml"), include_str!("../preset/keymap.toml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn theme(p: &Path) -> Result<String> {
|
pub(crate) fn theme(p: &Path) -> Result<Cow<str>> {
|
||||||
let Ok(user) = std::fs::read_to_string(p.join("theme.toml")) else {
|
let Ok(user) = std::fs::read_to_string(p.join("theme.toml")) else {
|
||||||
return Ok(include_str!("../preset/theme.toml").to_owned());
|
return Ok(include_str!("../preset/theme.toml").into());
|
||||||
};
|
};
|
||||||
let Some(use_) = Flavor::parse_use(&user) else {
|
let Some(use_) = Flavor::parse_use(&user) else {
|
||||||
return Self::merge_str(&user, include_str!("../preset/theme.toml"));
|
return Self::merge_str(&user, include_str!("../preset/theme.toml"));
|
||||||
@ -37,18 +37,18 @@ impl Preset {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn merge_str(user: &str, base: &str) -> Result<String> {
|
pub(crate) fn merge_str(user: &str, base: &str) -> Result<Cow<'static, str>> {
|
||||||
let mut t = user.parse()?;
|
let mut t = user.parse()?;
|
||||||
Self::merge(&mut t, base.parse()?, 2);
|
Self::merge(&mut t, base.parse()?, 2);
|
||||||
|
|
||||||
Ok(t.to_string())
|
Ok(t.to_string().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn merge_path(user: PathBuf, base: &str) -> Result<String> {
|
fn merge_path(user: PathBuf, base: &str) -> Result<Cow<str>> {
|
||||||
let s = std::fs::read_to_string(&user).unwrap_or_default();
|
let s = std::fs::read_to_string(&user).unwrap_or_default();
|
||||||
if s.is_empty() {
|
if s.is_empty() {
|
||||||
return Ok(base.to_string());
|
return Ok(base.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::merge_str(&s, base).with_context(|| anyhow!("Loading {user:?}"))
|
Self::merge_str(&s, base).with_context(|| anyhow!("Loading {user:?}"))
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
use std::{path::PathBuf, time::{self, SystemTime}};
|
use std::{path::PathBuf, str::FromStr, time::{self, SystemTime}};
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
use yazi_shared::fs::expand_path;
|
use yazi_shared::fs::expand_path;
|
||||||
|
|
||||||
use crate::{validation::check_validation, Xdg, MERGED_YAZI};
|
use crate::Xdg;
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub struct Preview {
|
pub struct Preview {
|
||||||
@ -22,8 +23,18 @@ pub struct Preview {
|
|||||||
pub ueberzug_offset: (f32, f32, f32, f32),
|
pub ueberzug_offset: (f32, f32, f32, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Preview {
|
impl Preview {
|
||||||
fn default() -> Self {
|
#[inline]
|
||||||
|
pub fn tmpfile(&self, prefix: &str) -> PathBuf {
|
||||||
|
let nanos = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_nanos();
|
||||||
|
self.cache_dir.join(format!("{prefix}-{}", nanos / 1000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Preview {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
preview: Shadow,
|
preview: Shadow,
|
||||||
@ -46,14 +57,14 @@ impl Default for Preview {
|
|||||||
ueberzug_offset: (f32, f32, f32, f32),
|
ueberzug_offset: (f32, f32, f32, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
let preview = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().preview;
|
let preview = toml::from_str::<Outer>(s)?.preview;
|
||||||
check_validation(preview.validate());
|
preview.validate()?;
|
||||||
|
|
||||||
let cache_dir =
|
let cache_dir =
|
||||||
preview.cache_dir.filter(|p| !p.is_empty()).map_or_else(Xdg::cache_dir, expand_path);
|
preview.cache_dir.filter(|p| !p.is_empty()).map_or_else(Xdg::cache_dir, expand_path);
|
||||||
std::fs::create_dir_all(&cache_dir).expect("Failed to create cache directory");
|
std::fs::create_dir_all(&cache_dir).context("Failed to create cache directory")?;
|
||||||
|
|
||||||
Preview {
|
Ok(Preview {
|
||||||
tab_size: preview.tab_size,
|
tab_size: preview.tab_size,
|
||||||
max_width: preview.max_width,
|
max_width: preview.max_width,
|
||||||
max_height: preview.max_height,
|
max_height: preview.max_height,
|
||||||
@ -66,14 +77,6 @@ impl Default for Preview {
|
|||||||
|
|
||||||
ueberzug_scale: preview.ueberzug_scale,
|
ueberzug_scale: preview.ueberzug_scale,
|
||||||
ueberzug_offset: preview.ueberzug_offset,
|
ueberzug_offset: preview.ueberzug_offset,
|
||||||
}
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Preview {
|
|
||||||
#[inline]
|
|
||||||
pub fn tmpfile(&self, prefix: &str) -> PathBuf {
|
|
||||||
let nanos = SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap().as_nanos();
|
|
||||||
self.cache_dir.join(format!("{prefix}-{}", nanos / 1000))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use crate::{validation::check_validation, MERGED_YAZI};
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Validate)]
|
#[derive(Debug, Deserialize, Validate)]
|
||||||
pub struct Tasks {
|
pub struct Tasks {
|
||||||
#[validate(range(min = 1, message = "Cannot be less than 1"))]
|
#[validate(range(min = 1, message = "Cannot be less than 1"))]
|
||||||
@ -18,16 +18,18 @@ pub struct Tasks {
|
|||||||
pub suppress_preload: bool,
|
pub suppress_preload: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Tasks {
|
impl FromStr for Tasks {
|
||||||
fn default() -> Self {
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
tasks: Tasks,
|
tasks: Tasks,
|
||||||
}
|
}
|
||||||
|
|
||||||
let tasks = toml::from_str::<Outer>(&MERGED_YAZI).unwrap().tasks;
|
let tasks = toml::from_str::<Outer>(s)?.tasks;
|
||||||
check_validation(tasks.validate());
|
tasks.validate()?;
|
||||||
|
|
||||||
tasks
|
Ok(tasks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
use std::path::PathBuf;
|
use std::{path::PathBuf, str::FromStr};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
use yazi_shared::{fs::expand_path, theme::Style, Xdg};
|
use yazi_shared::{fs::expand_path, theme::Style, Xdg};
|
||||||
|
|
||||||
use super::{Filetype, Flavor, Icons};
|
use super::{Filetype, Flavor, Icons};
|
||||||
use crate::{validation::check_validation, MERGED_THEME};
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
@ -27,12 +26,13 @@ pub struct Theme {
|
|||||||
pub icons: Icons,
|
pub icons: Icons,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Theme {
|
impl FromStr for Theme {
|
||||||
fn default() -> Self {
|
type Err = anyhow::Error;
|
||||||
let mut theme: Self = toml::from_str(&MERGED_THEME).unwrap();
|
|
||||||
|
|
||||||
check_validation(theme.manager.validate());
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
check_validation(theme.which.validate());
|
let mut theme: Self = toml::from_str(s)?;
|
||||||
|
theme.manager.validate()?;
|
||||||
|
theme.which.validate()?;
|
||||||
|
|
||||||
if theme.flavor.use_.is_empty() {
|
if theme.flavor.use_.is_empty() {
|
||||||
theme.manager.syntect_theme = expand_path(&theme.manager.syntect_theme);
|
theme.manager.syntect_theme = expand_path(&theme.manager.syntect_theme);
|
||||||
@ -41,7 +41,7 @@ impl Default for Theme {
|
|||||||
Xdg::config_dir().join(format!("flavors/{}.yazi/tmtheme.xml", theme.flavor.use_));
|
Xdg::config_dir().join(format!("flavors/{}.yazi/tmtheme.xml", theme.flavor.use_));
|
||||||
}
|
}
|
||||||
|
|
||||||
theme
|
Ok(theme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
use std::{borrow::Cow, process};
|
|
||||||
|
|
||||||
use validator::{ValidationErrors, ValidationErrorsKind};
|
|
||||||
|
|
||||||
pub fn check_validation(res: Result<(), ValidationErrors>) {
|
|
||||||
let Err(errors) = res else { return };
|
|
||||||
|
|
||||||
for (field, kind) in errors.into_errors() {
|
|
||||||
match kind {
|
|
||||||
ValidationErrorsKind::Struct(errors) => check_validation(Err(*errors)),
|
|
||||||
ValidationErrorsKind::List(errors) => {
|
|
||||||
for (i, errors) in errors {
|
|
||||||
eprint!("Config `{field}[{i}]` format error: ");
|
|
||||||
check_validation(Err(*errors));
|
|
||||||
eprintln!();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ValidationErrorsKind::Field(error) => {
|
|
||||||
for e in error {
|
|
||||||
eprintln!(
|
|
||||||
"Config `{field}` format error: {}\n",
|
|
||||||
e.message.unwrap_or(Cow::Borrowed("unknown error"))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
@ -1,8 +1,9 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
|
|
||||||
use super::SortBy;
|
use super::SortBy;
|
||||||
use crate::MERGED_YAZI;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Validate)]
|
#[derive(Debug, Deserialize, Serialize, Validate)]
|
||||||
pub struct Which {
|
pub struct Which {
|
||||||
@ -13,13 +14,15 @@ pub struct Which {
|
|||||||
pub sort_translit: bool,
|
pub sort_translit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Which {
|
impl FromStr for Which {
|
||||||
fn default() -> Self {
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
which: Which,
|
which: Which,
|
||||||
}
|
}
|
||||||
|
|
||||||
toml::from_str::<Outer>(&MERGED_YAZI).unwrap().which
|
Ok(toml::from_str::<Outer>(s)?.which)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,11 @@ impl Tasks {
|
|||||||
|
|
||||||
for p in PLUGIN.fetchers(&f.url, mime, factors) {
|
for p in PLUGIN.fetchers(&f.url, mime, factors) {
|
||||||
match loaded.get_mut(&f.url) {
|
match loaded.get_mut(&f.url) {
|
||||||
Some(n) if *n & (1 << p.id) != 0 => continue,
|
Some(n) if *n & (1 << p.idx) != 0 => continue,
|
||||||
Some(n) => *n |= 1 << p.id,
|
Some(n) => *n |= 1 << p.idx,
|
||||||
None => _ = loaded.insert(f.url.clone(), 1 << p.id),
|
None => _ = loaded.insert(f.url.clone(), 1 << p.idx),
|
||||||
}
|
}
|
||||||
tasks[p.id as usize].push(f.clone());
|
tasks[p.idx as usize].push(f.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,9 +41,9 @@ impl Tasks {
|
|||||||
let mime = if f.is_dir() { Some(MIME_DIR) } else { mimetype.get(&f.url).map(|s| &**s) };
|
let mime = if f.is_dir() { Some(MIME_DIR) } else { mimetype.get(&f.url).map(|s| &**s) };
|
||||||
for p in PLUGIN.preloaders(&f.url, mime) {
|
for p in PLUGIN.preloaders(&f.url, mime) {
|
||||||
match loaded.get_mut(&f.url) {
|
match loaded.get_mut(&f.url) {
|
||||||
Some(n) if *n & (1 << p.id) != 0 => continue,
|
Some(n) if *n & (1 << p.idx) != 0 => continue,
|
||||||
Some(n) => *n |= 1 << p.id,
|
Some(n) => *n |= 1 << p.idx,
|
||||||
None => _ = loaded.insert(f.url.clone(), 1 << p.id),
|
None => _ = loaded.insert(f.url.clone(), 1 << p.idx),
|
||||||
}
|
}
|
||||||
self.scheduler.preload_paged(p, f);
|
self.scheduler.preload_paged(p, f);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ yazi-proxy = { path = "../yazi-proxy", version = "0.2.5" }
|
|||||||
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
|
||||||
|
|
||||||
# External dependencies
|
# External dependencies
|
||||||
ansi-to-tui = "3.1.0"
|
ansi-to-tui = "=3.1.0"
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.86"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
crossterm = "0.27.0"
|
crossterm = "0.27.0"
|
||||||
|
@ -30,4 +30,4 @@ tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_lev
|
|||||||
libc = "0.2.155"
|
libc = "0.2.155"
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||||
trash = "4.1.1"
|
trash = "5.0.0"
|
||||||
|
@ -24,8 +24,5 @@ serde = { version = "1.0.203", features = [ "derive" ] }
|
|||||||
shell-words = "1.1.0"
|
shell-words = "1.1.0"
|
||||||
tokio = { version = "1.38.0", features = [ "full" ] }
|
tokio = { version = "1.38.0", features = [ "full" ] }
|
||||||
|
|
||||||
# Logging
|
|
||||||
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
|
|
||||||
|
|
||||||
[target."cfg(unix)".dependencies]
|
[target."cfg(unix)".dependencies]
|
||||||
libc = "0.2.155"
|
libc = "0.2.155"
|
||||||
|
@ -13,7 +13,7 @@ impl<T> RoCell<T> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn init(&self, value: T) {
|
pub fn init(&self, value: T) {
|
||||||
debug_assert!(!self.is_initialized());
|
debug_assert!(!self.initialized());
|
||||||
unsafe {
|
unsafe {
|
||||||
*self.0.get() = Some(value);
|
*self.0.get() = Some(value);
|
||||||
}
|
}
|
||||||
@ -29,25 +29,25 @@ impl<T> RoCell<T> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn replace(&self, value: T) -> T {
|
pub fn replace(&self, value: T) -> T {
|
||||||
debug_assert!(self.is_initialized());
|
debug_assert!(self.initialized());
|
||||||
unsafe { mem::replace(&mut *self.0.get(), Some(value)).unwrap_unchecked() }
|
unsafe { mem::replace(&mut *self.0.get(), Some(value)).unwrap_unchecked() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn drop(&self) -> T {
|
pub fn drop(&self) -> T {
|
||||||
debug_assert!(self.is_initialized());
|
debug_assert!(self.initialized());
|
||||||
unsafe { mem::take(&mut *self.0.get()).unwrap_unchecked() }
|
unsafe { mem::take(&mut *self.0.get()).unwrap_unchecked() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_initialized(&self) -> bool { unsafe { (*self.0.get()).is_some() } }
|
fn initialized(&self) -> bool { unsafe { (*self.0.get()).is_some() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Deref for RoCell<T> {
|
impl<T> Deref for RoCell<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
debug_assert!(self.is_initialized());
|
debug_assert!(self.initialized());
|
||||||
unsafe { (*self.0.get()).as_ref().unwrap_unchecked() }
|
unsafe { (*self.0.get()).as_ref().unwrap_unchecked() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user