//! # UniCase //! //! UniCase provides a way of specifying strings that are case-insensitive. //! //! UniCase supports full [Unicode case //! folding](https://www.w3.org/International/wiki/Case_folding). It can also //! utilize faster ASCII case comparisons, if both strings are ASCII. //! //! Using the `UniCase::new()` constructor will check the string to see if it //! is all ASCII. When a `UniCase` is compared against another, if both are //! ASCII, it will use the faster comparison. //! //! There also exists the `Ascii` type in this crate, which will always assume //! to use the ASCII case comparisons, if the encoding is already known. //! //! ## Example //! //! ```rust //! use unicase::UniCase; //! //! let a = UniCase::new("Maße"); //! let b = UniCase::new("MASSE"); //! let c = UniCase::new("mase"); //! //! assert_eq!(a, b); //! assert!(b != c); //! ``` //! //! ## Ascii //! //! ```rust //! use unicase::Ascii; //! //! let a = Ascii::new("foobar"); //! let b = Ascii::new("FoObAr"); //! //! assert_eq!(a, b); //! ```
#[cfg(feature = "nightly")] externcrate test;
#[cfg(all(__unicase__core_and_alloc, not(test)))] externcrate alloc; #[cfg(all(__unicase__core_and_alloc, not(test)))] use alloc::string::String;
#[cfg(not(all(__unicase__core_and_alloc, not(test))))] externcrate std as alloc; #[cfg(not(all(__unicase__core_and_alloc, not(test))))] externcrate std as core;
use alloc::borrow::Cow; #[cfg(__unicase__iter_cmp)] use core::cmp::Ordering; use core::fmt; use core::hash::{Hash, Hasher}; use core::ops::{Deref, DerefMut}; use core::str::FromStr;
useself::unicode::Unicode;
mod ascii; mod unicode;
/// Case Insensitive wrapper of strings. #[derive(Clone, Copy)] pubstruct UniCase<S>(Encoding<S>);
/// Case Insensitive wrapper of Ascii strings. #[derive(Clone, Copy, Debug, Default)] pubstruct Ascii<S>(S);
/// Compare two string-like types for case-less equality, using unicode folding. /// /// Equivalent to `UniCase::new(left) == UniCase::new(right)`. /// /// Note: This will perform a scan for ASCII characters before doing the /// the comparison. See `UniCase` for more information. #[inline] pubfn eq<S: AsRef<str> + ?Sized>(left: &S, right: &S) -> bool {
UniCase::new(left) == UniCase::new(right)
}
impl<S: AsRef<str>> UniCase<S> { /// Creates a new `UniCase`. /// /// Note: This scans the text to determine if it is all ASCII or not. pubfn new(s: S) -> UniCase<S> { #[cfg(not(__unicase__core_and_alloc))] #[allow(deprecated, unused)] use std::ascii::AsciiExt;
impl<S> UniCase<S> { /// Creates a new `UniCase`, skipping the ASCII check. #[cfg(__unicase__const_fns)] pubconstfn unicode(s: S) -> UniCase<S> {
UniCase(Encoding::Unicode(Unicode(s)))
}
/// Creates a new `UniCase`, skipping the ASCII check. /// /// For Rust versions >= 1.31, this is a `const fn`. #[cfg(not(__unicase__const_fns))] pubfn unicode(s: S) -> UniCase<S> {
UniCase(Encoding::Unicode(Unicode(s)))
}
/// Creates a new `UniCase` which performs only ASCII case folding. #[cfg(__unicase__const_fns)] pubconstfn ascii(s: S) -> UniCase<S> {
UniCase(Encoding::Ascii(Ascii(s)))
}
/// Creates a new `UniCase` which performs only ASCII case folding. /// /// For Rust versions >= 1.31, this is a `const fn`. #[cfg(not(__unicase__const_fns))] pubfn ascii(s: S) -> UniCase<S> {
UniCase(Encoding::Ascii(Ascii(s)))
}
/// Return `true` if this instance will only perform ASCII case folding. pubfn is_ascii(&self) -> bool { matchself.0 {
Encoding::Ascii(_) => true,
Encoding::Unicode(_) => false,
}
}
/// Unwraps the inner value held by this `UniCase`. #[inline] pubfn into_inner(self) -> S { matchself.0 {
Encoding::Ascii(s) => s.0,
Encoding::Unicode(s) => s.0,
}
}
}
impl<S> Deref for UniCase<S> { type Target = S; #[inline] fn deref<'a>(&'a self) -> &'a S {
inner!(self.0)
}
}
impl<S> DerefMut for UniCase<S> { #[inline] fn deref_mut<'a>(&'a mutself) -> &'a mut S {
inner!(mutself.0)
}
}
impl<S: FromStr + AsRef<str>> FromStr for UniCase<S> { type Err = <S as FromStr>::Err; fn from_str(s: &str) -> Result<UniCase<S>, Self::Err> {
s.parse().map(UniCase::new)
}
}
#[cfg(test)] mod tests { usesuper::UniCase; use std::hash::{Hash, Hasher}; #[cfg(not(__unicase__default_hasher))] use std::hash::SipHasher as DefaultHasher; #[cfg(__unicase__default_hasher)] use std::collections::hash_map::DefaultHasher;
#[test] fn test_eq_unicode() { let a = UniCase::new("στιγμας"); let b = UniCase::new("στιγμασ");
assert_eq!(a, b);
assert_eq!(b, a);
assert_eq!(hash(&a), hash(&b));
}
#[cfg(feature = "nightly")] #[bench] fn bench_unicase_ascii(b: &mut ::test::Bencher) {
b.bytes = b"foobar".len() as u64; let x = UniCase::new("foobar"); let y = UniCase::new("FOOBAR");
b.iter(|| assert_eq!(x, y));
}
#[cfg(feature = "nightly")] static SUBJECT: &'static [u8] = b"ffoo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz oo bar baz quux herp derp";
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.