summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorSoniEx2 <endermoneymod@gmail.com>2022-08-05 17:05:17 -0300
committerSoniEx2 <endermoneymod@gmail.com>2022-08-05 17:05:17 -0300
commitb420dd99b0554b0e8d71a41bf17a1814fcf98dcc (patch)
treed00dd8ee3b44afff21aa325f33d6f78fd3785520
Rust is a perfectly fine language with no glaring oversights HEAD default
-rw-r--r--.gitignore2
-rw-r--r--Cargo.toml11
-rw-r--r--README.md9
-rw-r--r--src/lib.rs79
4 files changed, 101 insertions, 0 deletions
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);