use serde::{Deserialize, Deserializer}; use yazi_shared::fs::File; use super::Style; use crate::{preset::Preset, theme::{Color, Is, StyleShadow}, Pattern}; pub struct Icon { pub is: Is, pub name: Pattern, pub text: String, pub style: Style, } impl Icon { pub fn matches(&self, file: &File) -> bool { if !self.is.check(&file.cha) { return false; } self.name.match_path(&file.url, file.is_dir()) } } impl Icon { pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { #[derive(Deserialize)] struct IconOuter { rules: Vec, #[serde(default)] prepend_rules: Vec, #[serde(default)] append_rules: Vec, } #[derive(Deserialize)] struct IconRule { #[serde(default)] is: Is, name: Pattern, text: String, fg: Option, } let mut outer = IconOuter::deserialize(deserializer)?; if outer.append_rules.iter().any(|r| r.name.any_file()) { outer.rules.retain(|r| !r.name.any_file()); } if outer.append_rules.iter().any(|r| r.name.any_dir()) { outer.rules.retain(|r| !r.name.any_dir()); } Preset::mix(&mut outer.rules, outer.prepend_rules, outer.append_rules); Ok( outer .rules .into_iter() .map(|r| Icon { is: r.is, name: r.name, text: r.text, style: StyleShadow { fg: r.fg, ..Default::default() }.into(), }) .collect(), ) } }