From b420dd99b0554b0e8d71a41bf17a1814fcf98dcc Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Fri, 5 Aug 2022 17:05:17 -0300 Subject: Rust is a perfectly fine language with no glaring oversights --- .gitignore | 2 ++ Cargo.toml | 11 +++++++++ README.md | 9 +++++++ src/lib.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..61378c6 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "charx" +description = "A replacement for char::is_ascii*" +version = "1.0.0" +edition = "2021" +license = "0BSD" +readme = "README.md" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/README.md b/README.md new file mode 100644 index 0000000..d29b629 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +A replacement for char +====================== + +Because Rust's `char::is_ascii*` family of functions takes `&self`, it's +impossible to use them as patterns. This is inconsistent with the rest of +`char::is_*`, which takes `self`. + +This crate provides `char`-taking variants of the `is_ascii*` family of +functions. diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..91c7c36 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,79 @@ +// Copyright (C) 2022 Soni L. +// SPDX-License-Identifier: 0BSD + +//! A replacement for char +//! ====================== +//! +//! Because Rust's `char::is_ascii*` family of functions takes `&self`, it's +//! impossible to use them as patterns. This is inconsistent with the rest of +//! `char::is_*`, which takes `self`. +//! +//! This crate provides `char`-taking variants of the `is_ascii*` family of +//! functions. +//! +//! # Examples +//! +//! This works: +//! +//! ```rust +//! "hello".trim_start_matches(char::is_numeric); +//! ``` +//! +//! This doesn't: +//! +//! ```rust compile_fail +//! "hello".trim_start_matches(char::is_ascii_digit); +//! ``` +//! +//! This crate provides an alternative: +//! +//! ```rust +//! "hello".trim_start_matches(charx::is_ascii_digit); +//! ``` + +macro_rules! charx_fn { + ($name:ident) => { + #[doc=concat!("Same as [`char::", stringify!($name), "`] but takes `char` instead of `&char`.")] + /// + /// # Examples + /// + /// This doesn't compile: + /// + /// ```rust compile_fail + #[doc=concat!("\"hello\".trim_start_matches(char::", stringify!($name), ");")] + /// ``` + /// + /// But this does: + /// + /// ```rust + #[doc=concat!("\"hello\".trim_start_matches(charx::", stringify!($name), ");")] + /// ``` + #[inline(always)] + pub fn $name(c: char) -> bool { + char::$name(&c) + } + mod $name { + #[test] + fn test() { + for c in '\0'..='\u{10FFFF}' { + assert_eq!(char::$name(&c), crate::$name(c)); + } + } + } + }; + ($($name:ident)*) => { + $(charx_fn!($name);)* + }; +} + +charx_fn!(is_ascii +is_ascii_alphabetic +is_ascii_alphanumeric +is_ascii_control +is_ascii_digit +is_ascii_graphic +is_ascii_hexdigit +is_ascii_lowercase +is_ascii_punctuation +is_ascii_uppercase +is_ascii_whitespace); -- cgit v1.2.3