use std::borrow::{Borrow, Cow};
use std::ops::Deref;
use std::str::Utf8Error;
#[derive(Debug, PartialOrd, Ord, Eq, PartialEq)]
pub struct LinuxOsStr([u8]);
#[derive(Default, Debug, PartialOrd, Ord, Eq, PartialEq, Clone)]
pub struct LinuxOsString(Vec<u8>);
impl LinuxOsStr {
pub fn new() -> &'static Self {
Self::from_bytes(b"")
}
pub fn from_bytes(inner: &[u8]) -> &Self {
unsafe { &*(inner as *const [u8] as *const LinuxOsStr) }
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
pub fn to_str(&self) -> Result<&str, Utf8Error> {
std::str::from_utf8(self)
}
pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.as_bytes())
}
pub fn split_once(&self, separator: u8) -> Option<(&LinuxOsStr, &LinuxOsStr)> {
self.iter().position(|&b| b == separator).map(|idx| {
(
Self::from_bytes(&self[..idx]),
Self::from_bytes(&self[idx + 1..]),
)
})
}
pub fn rsplit_once(&self, separator: u8) -> Option<(&LinuxOsStr, &LinuxOsStr)> {
self.iter().rposition(|&b| b == separator).map(|idx| {
(
Self::from_bytes(&self[..idx]),
Self::from_bytes(&self[idx + 1..]),
)
})
}
pub fn split(&self, separator: u8) -> impl Iterator<Item = &LinuxOsStr> {
self.as_bytes()
.split(move |&b| b == separator)
.map(LinuxOsStr::from_bytes)
}
pub fn split_ascii_whitespace(&self) -> impl Iterator<Item = &LinuxOsStr> {
self.as_bytes()
.split(|b| b.is_ascii_whitespace())
.filter(|slice| !slice.is_empty())
.map(LinuxOsStr::from_bytes)
}
pub fn lines(&self) -> impl Iterator<Item = &LinuxOsStr> {
self.split(b'\n')
}
pub fn trim_ascii_whitespace(&self) -> &LinuxOsStr {
let input = self.as_bytes();
let mut first = None;
let mut last = None;
for (i, &c) in input.iter().enumerate() {
if !c.is_ascii_whitespace() {
first = Some(i);
break;
}
}
for (i, &c) in input.iter().enumerate().rev() {
if !c.is_ascii_whitespace() {
last = Some(i);
break;
}
}
if let (Some(first), Some(last)) = (first, last) {
Self::from_bytes(&input[first..=last])
} else {
Self::from_bytes(&input[0..0])
}
}
}
impl LinuxOsString {
pub fn from_vec(vec: Vec<u8>) -> Self {
Self(vec)
}
pub fn new() -> Self {
Self(Vec::new())
}
pub fn as_os_str(&self) -> &LinuxOsStr {
self
}
}
impl Borrow<LinuxOsStr> for LinuxOsString {
fn borrow(&self) -> &LinuxOsStr {
LinuxOsStr::from_bytes(&self.0)
}
}
impl ToOwned for LinuxOsStr {
type Owned = LinuxOsString;
fn to_owned(&self) -> LinuxOsString {
LinuxOsString::from_vec(self.0.to_owned())
}
}
impl Deref for LinuxOsString {
type Target = LinuxOsStr;
fn deref(&self) -> &LinuxOsStr {
LinuxOsStr::from_bytes(&self.0)
}
}
impl Deref for LinuxOsStr {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.0
}
}