0f736b1fc4
will only check users of such group also cleaned some code: - Input doesn't need to be UTF-8 valid. - Main fuction is dead-simple, very readable. - Added some modularity. - Add some docs on behavior details.
48 lines
1.2 KiB
Rust
48 lines
1.2 KiB
Rust
use std::{
|
|
ffi::{CStr, OsStr},
|
|
os::unix::ffi::OsStrExt as _,
|
|
};
|
|
|
|
pub trait SliceExt {
|
|
fn split_once_ch(&self, ch: u8) -> Option<(&[u8], &[u8])>;
|
|
}
|
|
|
|
impl SliceExt for [u8] {
|
|
fn split_once_ch(&self, ch: u8) -> Option<(&[u8], &[u8])> {
|
|
let (idx, _) = self.iter().enumerate().find(|(_, b)| **b == ch)?;
|
|
// SAFETY: idx is IN-OF-BOUNDS index of the slice
|
|
unsafe { Some((self.get_unchecked(0..idx), self.get_unchecked((idx + 1)..))) }
|
|
}
|
|
}
|
|
|
|
pub trait CStrExt {
|
|
fn to_os_str(&self) -> &OsStr;
|
|
fn split_ch(&self, ch: u8) -> Option<(&[u8], &CStr)>;
|
|
}
|
|
|
|
impl CStrExt for CStr {
|
|
fn to_os_str(&self) -> &OsStr {
|
|
OsStr::from_bytes(self.to_bytes())
|
|
}
|
|
|
|
fn split_ch(&self, ch: u8) -> Option<(&[u8], &CStr)> {
|
|
let self_slice = self.to_bytes_with_nul();
|
|
|
|
self_slice.split_once_ch(ch).map(|(k, v)| {
|
|
// # SAFETY split originated in a slice with final null byte, hence second split will be
|
|
// null terminated
|
|
(k, unsafe { Self::from_bytes_with_nul_unchecked(v) })
|
|
})
|
|
}
|
|
}
|
|
|
|
pub trait StrExt {
|
|
fn as_os_str(&self) -> &OsStr;
|
|
}
|
|
|
|
impl StrExt for str {
|
|
fn as_os_str(&self) -> &OsStr {
|
|
OsStr::from_bytes(self.as_bytes())
|
|
}
|
|
}
|