uncased/lib.rs
1//! Case-preserving, ASCII case-insensitive `no_std` string types.
2//!
3//! An _uncased_ string is case-preserving. That is, the string itself contains
4//! cased characters, but comparison (including ordering, equality, and hashing)
5//! is ASCII case-insensitive.
6//!
7//! ```rust
8//! use uncased::UncasedStr;
9//!
10//! let x: &UncasedStr = "hello!".into();
11//! let y: &UncasedStr = "HelLo!".into();
12//!
13//! assert_eq!(x, y);
14//! assert_eq!(x.as_str(), "hello!");
15//! assert_eq!(y.as_str(), "HelLo!");
16//!
17//! let x_sub = &x[..4];
18//! let y_sub = &y[..4];
19//! assert_eq!(x_sub, y_sub);
20//! assert_eq!(x_sub.as_str(), "hell");
21//! assert_eq!(y_sub.as_str(), "HelL");
22//! ```
23//!
24//! ## Unicode
25//!
26//! This crate _does not_ perform Unicode case-folding. For Unicode
27//! case-folding, see [`unicase`](https://crates.io/crates/unicase).
28//!
29//! ## Features and `no_std`
30//!
31//! Crate features:
32//!
33//! * `alloc` (_default_) - enables the [`Uncased`] type
34//! * `with-serde` - enables (de)serializing of [`UncasedStr`] via `serde`
35//! * `with-serde-alloc` - enables `alloc`, (de)serializing of [`UncasedStr`]
36//! and [`Uncased`] via `serde`
37//!
38//! This crate is `#![no_std]` compatible. By default, the `alloc` feature is
39//! enabled, which enables the [`Uncased`] type but requires `alloc` support. To
40//! disable the feature, disable this crate's default features:
41//!
42//! ```toml
43//! [dependencies]
44//! uncased = { version = "0.9", default-features = false }
45//! ```
46//!
47//! In addition to the `alloc` feature, support for (de)serializing `UncasedStr`
48//! with `serde` can be enabled via the `with-serde` feature. Support for
49//! (de)serserializing both `UncasedStr` and `Uncased` can be enabled via the
50//! `with-serde-alloc` feature, which implicitly enables the `alloc` feature.
51
52#![no_std]
53#![cfg_attr(nightly, feature(doc_cfg))]
54
55#[cfg(feature = "alloc")] extern crate alloc;
56
57#[cfg(feature = "serde")] mod serde;
58#[cfg(feature = "alloc")] mod owned;
59#[cfg(test)] mod tests;
60mod borrowed;
61mod as_uncased;
62
63#[cfg(feature = "alloc")] pub use owned::Uncased;
64pub use borrowed::UncasedStr;
65pub use as_uncased::AsUncased;
66
67/// Returns true if `s1` and `s2` are equal without considering case.
68///
69/// That is, this function returns `s1.to_ascii_lowercase() ==
70/// s2.to_ascii_lowercase()`, but does it in a much faster way. This is also
71/// equivalent to `UncasedStr::new(s1) == UncasedStr::new(s2)`.
72///
73/// # Example
74///
75/// ```rust
76/// assert!(uncased::eq("ENV", "env"));
77/// assert!(uncased::eq("bRoWN", "BROWN"));
78/// assert!(uncased::eq("hi", "HI"));
79/// assert!(uncased::eq("dogs are COOL!", "DOGS are cool!"));
80/// ```
81#[inline(always)]
82pub fn eq<S1: AsRef<str>, S2: AsRef<str>>(s1: S1, s2: S2) -> bool {
83 UncasedStr::new(s1.as_ref()) == UncasedStr::new(s2.as_ref())
84}