diff --git a/.travis.yml b/.travis.yml index 22761ba..ab99ec9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1 +1,6 @@ language: rust + +script: + - cargo build + - cargo test + - cargo test --no-default-features diff --git a/Cargo.toml b/Cargo.toml index ecaa08d..5190fff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,13 @@ [package] name = "caseless" -version = "0.2.1" +version = "0.2.2" authors = ["Simon Sapin "] description = "Unicode caseless matching" repository = "https://github.com/SimonSapin/rust-caseless" license = "MIT" +keywords = ["unicode", "string", "case-insensitive", "normalization", "no_std"] +categories = ["text-processing"] +readme = "README.md" build = "src/build.rs" @@ -12,4 +15,9 @@ build = "src/build.rs" regex = "1.0" [dependencies] -unicode-normalization = "0.1" +unicode-normalization = { version = "0.1", optional = true } + +[features] +default = ["alloc", "normalization"] +alloc = [] +normalization = ["unicode-normalization"] diff --git a/README.md b/README.md index ca6568f..ab39b79 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # rust-caseless Unicode caseless matching + +This crate can be used without libstd, when build without the default `alloc` +and `normalization` features. diff --git a/src/lib.rs b/src/lib.rs index 5dba244..97abc94 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,10 +1,15 @@ +#![cfg_attr(not(feature = "alloc"), no_std)] + +#[cfg(feature = "normalization")] use unicode_normalization::UnicodeNormalization; +#[cfg(feature = "normalization")] extern crate unicode_normalization; include!(concat!(env!("OUT_DIR"), "/case_folding_data.rs")); +#[cfg(feature = "normalization")] pub trait Caseless { fn default_case_fold(self) -> CaseFold where Self: Sized; fn default_caseless_match>(self, other: J) -> bool; @@ -12,6 +17,15 @@ pub trait Caseless { fn compatibility_caseless_match>(self, other: J) -> bool; } +#[cfg(not(feature = "normalization"))] +// This trait is private when the `normalization` feature is disabled. Otherwise, external crates +// implementing the version without the `normalization` methods might get linked into projects that +// do use the `normalization` feature, causing a trait mismatch error. +trait Caseless { + fn default_case_fold(self) -> CaseFold where Self: Sized; + fn default_caseless_match>(self, other: J) -> bool; +} + impl> Caseless for I { fn default_case_fold(self) -> CaseFold { CaseFold { @@ -25,6 +39,7 @@ impl> Caseless for I { other.default_case_fold()) } + #[cfg(feature = "normalization")] fn canonical_caseless_match>(self, other: J) -> bool { // FIXME: Inner NFD can be optimized: // "Normalization is not required before case folding, @@ -39,6 +54,7 @@ impl> Caseless for I { other.nfd().default_case_fold().nfd()) } + #[cfg(feature = "normalization")] fn compatibility_caseless_match>(self, other: J) -> bool { // FIXME: Unclear if the inner NFD can be optimized here like in canonical_caseless_match. iter_eq(self.nfd().default_case_fold().nfkd().default_case_fold().nfkd(), @@ -47,6 +63,7 @@ impl> Caseless for I { } +#[cfg(feature = "alloc")] pub fn default_case_fold_str(s: &str) -> String { s.chars().default_case_fold().collect() } @@ -55,10 +72,12 @@ pub fn default_caseless_match_str(a: &str, b: &str) -> bool { a.chars().default_caseless_match(b.chars()) } +#[cfg(feature = "normalization")] pub fn canonical_caseless_match_str(a: &str, b: &str) -> bool { a.chars().canonical_caseless_match(b.chars()) } +#[cfg(feature = "normalization")] pub fn compatibility_caseless_match_str(a: &str, b: &str) -> bool { a.chars().compatibility_caseless_match(b.chars()) } @@ -116,9 +135,10 @@ impl Iterator for CaseFold where I: Iterator { #[cfg(test)] mod tests { - use super::default_case_fold_str; + use super::*; #[test] + #[cfg(feature = "alloc")] fn test_strs() { assert_eq!(default_case_fold_str("Test Case"), "test case"); assert_eq!(default_case_fold_str("Teſt Caſe"), "test case");