aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornatsuoto <[email protected]>2026-07-11 16:42:40 +0530
committernatsuoto <[email protected]>2026-07-11 16:42:40 +0530
commit665c9b18a7bf1025aae26fb440efff4c2b0d31d0 (patch)
tree61fe523d260191cde707f67bb73eab9807f5675b
parent4c316804719f93f3c20e5bb0cf35d2bc5902fefe (diff)
downloadedify-665c9b18a7bf1025aae26fb440efff4c2b0d31d0.tar.xz
edify-665c9b18a7bf1025aae26fb440efff4c2b0d31d0.zip
refactor(library): rewrite numeric/ validators to fluent Pattern() chain
-rw-r--r--edify/library/numeric/hash.py14
-rw-r--r--edify/library/numeric/integer.py12
-rw-r--r--edify/library/numeric/number.py96
-rw-r--r--edify/library/numeric/ordinal.py18
-rw-r--r--edify/library/numeric/percentage.py21
-rw-r--r--edify/library/numeric/ratio.py13
-rw-r--r--edify/library/numeric/roman.py31
-rw-r--r--edify/library/numeric/scientific.py23
8 files changed, 201 insertions, 27 deletions
diff --git a/edify/library/numeric/hash.py b/edify/library/numeric/hash.py
index 1acfcd7..bd760ba 100644
--- a/edify/library/numeric/hash.py
+++ b/edify/library/numeric/hash.py
@@ -2,9 +2,19 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-hash = RegexBackedPattern(r"^[a-fA-F0-9]{8,128}$")
+hash = (
+ Pattern()
+ .start_of_input()
+ .between(8, 128)
+ .any_of()
+ .range("a", "f")
+ .range("A", "F")
+ .range("0", "9")
+ .end()
+ .end_of_input()
+)
"""Callable :class:`Pattern` for a hex-hash digest (8-128 hex characters,
covering CRC-32 through SHA-512).
"""
diff --git a/edify/library/numeric/integer.py b/edify/library/numeric/integer.py
index e29c4a0..5737758 100644
--- a/edify/library/numeric/integer.py
+++ b/edify/library/numeric/integer.py
@@ -2,7 +2,15 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-integer = RegexBackedPattern(r"^[+-]?\d+$")
+integer = (
+ Pattern()
+ .start_of_input()
+ .optional()
+ .any_of_chars("+-")
+ .one_or_more()
+ .digit()
+ .end_of_input()
+)
"""Callable :class:`Pattern` for a signed decimal integer."""
diff --git a/edify/library/numeric/number.py b/edify/library/numeric/number.py
index 03c6a45..8f316f5 100644
--- a/edify/library/numeric/number.py
+++ b/edify/library/numeric/number.py
@@ -2,20 +2,90 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern, any_of
-number = RegexBackedPattern(
- r"^(?:"
- r"[+-]?\d+"
- r"|[+-]?\d+\.\d+"
- r"|[+-]?\.\d+"
- r"|[+-]?\d+\.\d*[eE][+-]?\d+"
- r"|[+-]?\d+[eE][+-]?\d+"
- r"|0[xX][0-9a-fA-F]+"
- r"|0[oO][0-7]+"
- r"|0[bB][01]+"
- r"|[+-]?\d+(?:\.\d+)?[+-]\d+(?:\.\d+)?[jJi]"
- r")$"
+
+def _sign() -> Pattern:
+ return Pattern().optional().any_of_chars("+-")
+
+
+_int = Pattern().subexpression(_sign()).one_or_more().digit()
+_dec = (
+ Pattern()
+ .subexpression(_sign())
+ .one_or_more()
+ .digit()
+ .char(".")
+ .one_or_more()
+ .digit()
+)
+_ldec = Pattern().subexpression(_sign()).char(".").one_or_more().digit()
+_sci_dec = (
+ Pattern()
+ .subexpression(_sign())
+ .one_or_more()
+ .digit()
+ .char(".")
+ .zero_or_more()
+ .digit()
+ .any_of_chars("eE")
+ .optional()
+ .any_of_chars("+-")
+ .one_or_more()
+ .digit()
+)
+_sci_int = (
+ Pattern()
+ .subexpression(_sign())
+ .one_or_more()
+ .digit()
+ .any_of_chars("eE")
+ .optional()
+ .any_of_chars("+-")
+ .one_or_more()
+ .digit()
+)
+_hex = (
+ Pattern()
+ .char("0")
+ .any_of_chars("xX")
+ .one_or_more()
+ .any_of()
+ .range("0", "9")
+ .range("a", "f")
+ .range("A", "F")
+ .end()
+)
+_oct = Pattern().char("0").any_of_chars("oO").one_or_more().range("0", "7")
+_bin = Pattern().char("0").any_of_chars("bB").one_or_more().any_of_chars("01")
+_complex = (
+ Pattern()
+ .subexpression(_sign())
+ .one_or_more()
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
+ .end()
+ .any_of_chars("+-")
+ .one_or_more()
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
+ .end()
+ .any_of_chars("jJi")
+)
+
+number = (
+ Pattern()
+ .start_of_input()
+ .subexpression(any_of(_int, _dec, _ldec, _sci_dec, _sci_int, _hex, _oct, _bin, _complex))
+ .end_of_input()
)
"""Callable :class:`Pattern` that accepts numbers in any base or form:
signed integers, decimals, floats, scientific, hex (``0x``), octal (``0o``),
diff --git a/edify/library/numeric/ordinal.py b/edify/library/numeric/ordinal.py
index 9bae4c6..138b5e6 100644
--- a/edify/library/numeric/ordinal.py
+++ b/edify/library/numeric/ordinal.py
@@ -2,7 +2,21 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-ordinal = RegexBackedPattern(r"^\d+(?:st|nd|rd|th)$")
+ordinal = (
+ Pattern()
+ .start_of_input()
+ .one_or_more()
+ .digit()
+ .group()
+ .any_of()
+ .string("st")
+ .string("nd")
+ .string("rd")
+ .string("th")
+ .end()
+ .end()
+ .end_of_input()
+)
"""Callable :class:`Pattern` for an English ordinal number."""
diff --git a/edify/library/numeric/percentage.py b/edify/library/numeric/percentage.py
index f404450..38299ce 100644
--- a/edify/library/numeric/percentage.py
+++ b/edify/library/numeric/percentage.py
@@ -2,9 +2,26 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-percentage = RegexBackedPattern(r"^-?\d+(?:\.\d+)?\s?%$")
+percentage = (
+ Pattern()
+ .start_of_input()
+ .optional()
+ .char("-")
+ .one_or_more()
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
+ .end()
+ .optional()
+ .whitespace_char()
+ .char("%")
+ .end_of_input()
+)
"""Callable :class:`Pattern` for a percentage value: signed number optionally
with a decimal part and a trailing ``%``.
"""
diff --git a/edify/library/numeric/ratio.py b/edify/library/numeric/ratio.py
index 7507d6c..49ae1c7 100644
--- a/edify/library/numeric/ratio.py
+++ b/edify/library/numeric/ratio.py
@@ -2,7 +2,16 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-ratio = RegexBackedPattern(r"^\d+:\d+$")
+ratio = (
+ Pattern()
+ .start_of_input()
+ .one_or_more()
+ .digit()
+ .char(":")
+ .one_or_more()
+ .digit()
+ .end_of_input()
+)
"""Callable :class:`Pattern` for a ratio shape: ``digits:digits``."""
diff --git a/edify/library/numeric/roman.py b/edify/library/numeric/roman.py
index 2abad73..942f0ac 100644
--- a/edify/library/numeric/roman.py
+++ b/edify/library/numeric/roman.py
@@ -2,7 +2,34 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-roman = RegexBackedPattern(r"^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$")
+roman = (
+ Pattern()
+ .start_of_input()
+ .between(0, 3)
+ .char("M")
+ .group()
+ .any_of()
+ .string("CM")
+ .string("CD")
+ .subexpression(Pattern().optional().char("D").between(0, 3).char("C"))
+ .end()
+ .end()
+ .group()
+ .any_of()
+ .string("XC")
+ .string("XL")
+ .subexpression(Pattern().optional().char("L").between(0, 3).char("X"))
+ .end()
+ .end()
+ .group()
+ .any_of()
+ .string("IX")
+ .string("IV")
+ .subexpression(Pattern().optional().char("V").between(0, 3).char("I"))
+ .end()
+ .end()
+ .end_of_input()
+)
"""Callable :class:`Pattern` for a Roman-numeral value 1-3999."""
diff --git a/edify/library/numeric/scientific.py b/edify/library/numeric/scientific.py
index a2044e7..2795aa7 100644
--- a/edify/library/numeric/scientific.py
+++ b/edify/library/numeric/scientific.py
@@ -2,7 +2,26 @@
from __future__ import annotations
-from edify.library._support.regex import RegexBackedPattern
+from edify import Pattern
-scientific = RegexBackedPattern(r"^[+-]?\d+(?:\.\d+)?[eE][+-]?\d+$")
+scientific = (
+ Pattern()
+ .start_of_input()
+ .optional()
+ .any_of_chars("+-")
+ .one_or_more()
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
+ .end()
+ .any_of_chars("eE")
+ .optional()
+ .any_of_chars("+-")
+ .one_or_more()
+ .digit()
+ .end_of_input()
+)
"""Callable :class:`Pattern` for scientific-notation shape."""