use std::collections::HashMap;
pub fn resolve_uid(name: &str) -> Option<u32> {
if let Ok(uid) = name.parse::<u32>() {
return Some(uid);
}
let contents = std::fs::read_to_string("/etc/passwd").ok()?;
for line in contents.lines() {
let fields: Vec<&str> = line.split(':').collect();
if fields.len() >= 3 && fields[0] == name {
return fields[2].parse().ok();
}
}
None
}
pub fn uid_to_name(uid: u32) -> Option<String> {
let contents = std::fs::read_to_string("/etc/passwd").ok()?;
for line in contents.lines() {
let fields: Vec<&str> = line.split(':').collect();
if fields.len() >= 3
&& let Ok(file_uid) = fields[2].parse::<u32>()
&& file_uid == uid
{
return Some(fields[0].to_string());
}
}
None
}
pub struct UidCache {
map: HashMap<u32, String>,
}
impl UidCache {
pub fn new() -> Self {
Self {
map: HashMap::new(),
}
}
pub fn get(&mut self, uid: u32) -> &str {
self.map.entry(uid).or_insert_with(|| {
uid_to_name(uid).unwrap_or_else(|| uid.to_string())
})
}
}
impl Default for UidCache {
fn default() -> Self {
Self::new()
}
}