use crate::{Error, Result};
use std::str::FromStr;
#[derive(Debug)]
pub struct Lock {
id: usize,
class: String,
mode: String,
rw: String,
pid: usize,
major: usize,
minor: usize,
inode: usize,
start: usize,
end: Option<usize>,
}
impl Lock {
getter_gen! {
id: usize,
class: String,
mode: String,
rw: String,
pid: usize,
major: usize,
minor: usize,
inode: usize,
start: usize,
end: Option<usize>
}
#[allow(clippy::useless_format)]
pub fn column(&self, index: usize) -> String {
match index {
0 => format!("{}", self.id),
1 => format!("{}", self.class),
2 => format!("{}", self.mode),
3 => format!("{}", self.rw),
4 => format!("{}", self.pid),
5 => format!("{:02x}:{:02x}:{}", self.major, self.minor, self.inode),
6 => format!("{}", self.start),
7 => {
if let Some(e) = self.end {
format!("{}", e)
} else {
format!("{}", "EOF")
}
}
_ => panic!("out of range"),
}
}
}
impl FromStr for Lock {
type Err = Error;
fn from_str(value: &str) -> Result<Self> {
let columns: Vec<&str> = value.trim().split_ascii_whitespace().collect();
if columns.len() != 8 {
return Err(Error::BadFormat);
}
let id = columns[0].trim_end_matches(':').parse::<usize>()?;
let class = columns[1].to_string();
let mode = columns[2].to_string();
let rw = columns[3].to_string();
let pid = columns[4].parse::<usize>()?;
let file: Vec<&str> = columns[5].split(':').collect();
if file.len() != 3 {
return Err(Error::BadFormat);
}
let major = usize::from_str_radix(file[0], 16)?;
let minor = usize::from_str_radix(file[1], 16)?;
let inode = usize::from_str_radix(file[2], 10)?;
let start = columns[6].parse::<usize>()?;
let end = if "EOF" == columns[7] {
None
} else {
Some(columns[7].parse::<usize>()?)
};
Ok(Lock {
id,
class,
mode,
rw,
pid,
major,
minor,
inode,
start,
end,
})
}
}
#[inline(always)]
fn to_locks(line: &str) -> Result<Lock> {
Lock::from_str(line)
}
default_list! {
locks, "/proc/locks", Lock, to_locks
}