encoding8 0.3.2

various 8-bit encodings
Documentation
use std::borrow::{Borrow, BorrowMut};
use std::path::Path;

/// ASCII represents 7-bit values in the range 0..=127.
/// ASCII implements AsRef, Borrow, BorrowMut, and AsRef for String, so it can be used as a string type
/// &ASCII acts as an iterator over it's bytes
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)
    }
    /// is_lowercase returns true if all characters are lowercase
    /// ```
    /// # use encoding8::ascii::ASCII;
    /// assert!(ASCII::from_str("foo").unwrap().is_lowercase());
    /// assert!(!ASCII::from_str("AM1").unwrap().is_lowercase());
    /// ```
    pub fn is_lowercase(&self) -> bool {
        self.all(super::is_lowercase)
    }

    /// is_numeric returns true if all characters are lowercase
    /// ```
    /// # use encoding8::ascii::ASCII;
    /// assert!(ASCII::from_str("1234456789").unwrap().is_numeric());
    /// assert!(!ASCII::from_str("AM1").unwrap().is_numeric());
    /// ```
    pub fn is_numeric(&self) -> bool {
        self.all(super::is_numeric)
    }

    /// is_alphanumeric returns true if all characters are digits or alphabetical
    ///  ```
    /// # use encoding8::ascii::ASCII;
    /// assert!(ASCII::from_str("aDA1234456789").unwrap().is_alphanumeric());
    /// assert!(!ASCII::from_str("<>").unwrap().is_alphanumeric());
    /// ```
    pub fn is_alphanumeric(&self) -> bool {
        self.all(super::is_alphanumeric)
    }

    /// is_alphabetical returns true if all characters are alphabetical; i.e, in b'a'..=b'z' or b'A'..=b'Z'
    /// ```
    /// # use encoding8::ascii::ASCII;
    /// assert!(ASCII::from_str("fooBAR").unwrap().is_alphabetical());
    /// assert!(!ASCII::from_str("AM1").unwrap().is_alphabetical());
    /// ```
    pub fn is_alphabetical(&self) -> bool {
        self.all(super::is_alphabetical)
    }

    /// from_bytes_unchecked creates ASCII from bytes. this assumes that all bytes are seven-bit!
    /// use at your own risk!
    pub unsafe fn from_bytes_unchecked<I>(bytes: I) -> Self
    where
        I: IntoIterator<Item = u8>,
    {
        ASCII(String::from_utf8_unchecked(bytes.into_iter().collect()))
    }
    ///from_str converts a string to ASCII, if it comprised soley of ASCII characters.
    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()
    }
}