use crate::{Result, Error, error};
use std::str::FromStr;
use std::fmt::{self, Display};
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(rename_all = "kebab-case"))]
pub struct User
{
pub name: Option<String>,
pub id: libc::uid_t
}
#[derive(Default, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(rename_all = "kebab-case"))]
pub struct Group
{
pub name: Option<String>,
pub id: libc::gid_t
}
impl User
{
pub fn new(name: Option<&str>, id: libc::uid_t) -> Self
{
let mut r = Self::default();
if let Some(name) = name
{
r.name = Some(name.to_owned());
}
r.id = id;
r
}
}
impl Group
{
pub fn new(name: Option<&str>, id: libc::gid_t) -> Self
{
let mut r = Self::default();
if let Some(name) = name
{
r.name = Some(name.to_owned());
}
r.id = id;
r
}
}
impl FromStr for User
{
type Err = Error;
fn from_str(s: &str) -> Result<Self>
{
let mut r = Self::default();
match s.split_once(':')
{
Some(parts) =>
{
if parts.0.starts_with('<')
&& parts.0.ends_with('>')
{
r.name = None
}
else
{
r.name = Some(parts.0.to_string())
}
r.id = parts.1.parse::<libc::uid_t>()?;
}
None => error!("Expected a value separator in 'user' field, got: '{s}'")
}
Ok(r)
}
}
impl FromStr for Group
{
type Err = Error;
fn from_str(s: &str) -> Result<Self>
{
let mut r = Self::default();
match s.split_once(':')
{
Some(parts) =>
{
if parts.0.starts_with('<')
&& parts.0.ends_with('>')
{
r.name = None
}
else
{
r.name = Some(parts.0.to_string())
}
r.id = parts.1.parse::<libc::gid_t>()?;
}
None => error!("Expected a value separator in 'group' field, got: '{s}'")
}
Ok(r)
}
}
impl Display for User
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f,
"{}:{}",
if let Some(name) = &self.name { &name } else { "<unknown>" },
self.id
)
}
}
impl Display for Group
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f,
"{}:{}",
if let Some(name) = &self.name { &name } else { "<unknown>" },
self.id
)
}
}