use anyhow::{Result, ensure}; use serde::{Deserialize, Deserializer, de}; use yazi_shim::toml::DeserializeOverWith; use crate::{Mixable, Pattern, Selectable}; #[derive(Clone, Debug)] pub struct Selector { pub url: Option, pub mime: Option, } impl<'de> Deserialize<'de> for Selector { fn deserialize>(deserializer: D) -> Result { #[derive(Deserialize)] struct Shadow { url: Option, mime: Option, } let shadow = Shadow::deserialize(deserializer)?; Self::new(shadow.url, shadow.mime).map_err(de::Error::custom) } } impl DeserializeOverWith for Selector { fn deserialize_over_with<'de, D: Deserializer<'de>>( self, deserializer: D, ) -> Result { let new = Self::deserialize(deserializer)?; Self::new(new.url.or(self.url), new.mime.or(self.mime)).map_err(de::Error::custom) } } impl Selector { pub fn new(url: Option, mime: Option) -> Result { ensure!(url.is_some() || mime.is_some(), "at least one of `url` or `mime` must be specified"); Ok(Self { url, mime }) } } impl Selectable for Selector { fn url_pat(&self) -> Option<&Pattern> { self.url.as_ref() } fn mime_pat(&self) -> Option<&Pattern> { self.mime.as_ref() } } impl Mixable for Selector { fn any_file(&self) -> bool { self.url_pat().is_some_and(|p| p.any_file()) } fn any_dir(&self) -> bool { self.url_pat().is_some_and(|p| p.any_dir()) } }