use std::borrow::{Borrow, BorrowMut};
use std::path::Path;
pub struct ASCII(String);
impl ASCII {
fn all<F: FnMut(u8) -> bool>(&self, f: F) -> bool {
self.into_iter().all(f)
}
pub fn is_uppercase(&self) -> bool {
self.all(super::is_uppercase)
}
pub fn is_lowercase(&self) -> bool {
self.all(super::is_lowercase)
}
pub fn is_numeric(&self) -> bool {
self.all(super::is_numeric)
}
pub fn is_alphanumeric(&self) -> bool {
self.all(super::is_alphanumeric)
}
pub fn is_alphabetical(&self) -> bool {
self.all(super::is_alphabetical)
}
pub unsafe fn from_bytes_unchecked<I>(bytes: I) -> Self
where
I: IntoIterator<Item = u8>,
{
ASCII(String::from_utf8_unchecked(bytes.into_iter().collect()))
}
pub fn from_str(s: &str) -> Option<Self> {
if s.bytes().all(|b| b & 0x80 == 0) {
Some(ASCII(s.to_string()))
} else {
None
}
}
pub fn from_bytes<I>(bytes: I) -> Option<Self>
where
I: IntoIterator<Item = u8>,
{
let it = bytes.into_iter();
let (size, _) = it.size_hint();
let mut bytes = Vec::with_capacity(size);
for b in it {
if b & 0x80 != 0 {
return None;
}
bytes.push(b)
}
unsafe { Some(ASCII(String::from_utf8_unchecked(bytes))) }
}
pub fn to_lowercase(self) -> Self {
unsafe { ASCII::from_bytes_unchecked(self.into_iter().map(super::to_lowercase)) }
}
pub fn to_uppercase(self) -> Self {
unsafe { ASCII::from_bytes_unchecked(self.into_iter().map(super::to_uppercase)) }
}
}
impl<'a> IntoIterator for &'a ASCII {
type Item = u8;
type IntoIter = ::std::str::Bytes<'a>;
fn into_iter(self) -> Self::IntoIter {
self.0.bytes()
}
}
impl Borrow<str> for ASCII {
fn borrow(&self) -> &str {
&self.0
}
}
impl BorrowMut<str> for ASCII {
fn borrow_mut(&mut self) -> &mut str {
&mut self.0
}
}
impl AsRef<str> for ASCII {
fn as_ref(&self) -> &str {
&self.0
}
}
impl AsMut<str> for ASCII {
fn as_mut(&mut self) -> &mut str {
&mut self.0
}
}
impl AsRef<Path> for ASCII {
fn as_ref(&self) -> &Path {
self.0.as_ref()
}
}
impl Into<String> for ASCII {
fn into(self) -> String {
self.0
}
}
impl Into<Vec<u8>> for ASCII {
fn into(self) -> Vec<u8> {
self.0.into()
}
}