[ownership] change uid/gid storage to tristate enum for negation

This commit is contained in:
Alexandru Macovei 2018-07-01 00:45:28 +03:00 committed by David Peter
parent d7cc34e36f
commit 22a55361e0

View file

@ -3,8 +3,15 @@ use std::fs;
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
pub struct OwnerFilter { pub struct OwnerFilter {
uid: Option<u32>, uid: Check<u32>,
gid: Option<u32>, gid: Check<u32>,
}
#[derive(Clone, Copy, Debug, PartialEq)]
enum Check<T> {
Equal(T),
NotEq(T),
Ignore,
} }
impl OwnerFilter { impl OwnerFilter {
@ -39,7 +46,17 @@ impl OwnerFilter {
} }
}; };
if uid.is_none() && gid.is_none() { use self::Check::*;
let uid = match uid {
Some(u) => Equal(u),
_ => Ignore,
};
let gid = match gid {
Some(g) => Equal(g),
_ => Ignore,
};
if let (Ignore, Ignore) = (uid, gid) {
Err(anyhow!( Err(anyhow!(
"'{}' is not a valid user/group specifier. See 'fd --help'.", "'{}' is not a valid user/group specifier. See 'fd --help'.",
input input
@ -52,10 +69,17 @@ impl OwnerFilter {
pub fn matches(&self, md: &fs::Metadata) -> bool { pub fn matches(&self, md: &fs::Metadata) -> bool {
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
let uid_ok = self.uid.map(|u| u == md.uid()).unwrap_or(true); self.uid.check(md.uid()) && self.gid.check(md.gid())
let gid_ok = self.gid.map(|g| g == md.gid()).unwrap_or(true); }
}
uid_ok && gid_ok impl<T: PartialEq> Check<T> {
fn check(&self, v: T) -> bool {
match self {
Check::Equal(x) => v == *x,
Check::NotEq(x) => v != *x,
Check::Ignore => true,
}
} }
} }
@ -78,12 +102,13 @@ mod owner_parsing {
}; };
} }
use super::Check::*;
owner_tests! { owner_tests! {
empty: "" => Err(_), empty: "" => Err(_),
uid_only: "5" => Ok(OwnerFilter { uid: Some(5), gid: None }), uid_only: "5" => Ok(OwnerFilter { uid: Equal(5), gid: Ignore }),
uid_gid: "9:3" => Ok(OwnerFilter { uid: Some(9), gid: Some(3)}), uid_gid: "9:3" => Ok(OwnerFilter { uid: Equal(9), gid: Equal(3) }),
gid_only: ":8" => Ok(OwnerFilter { uid: None, gid: Some(8)}), gid_only: ":8" => Ok(OwnerFilter { uid: Ignore, gid: Equal(8) }),
colon_only: ":" => Err(_), colon_only: ":" => Err(_),
trailing: "5:" => Ok(OwnerFilter { uid: Some(5), gid: None }), trailing: "5:" => Ok(OwnerFilter { uid: Equal(5), gid: Ignore }),
} }
} }