From 05d83017ec249d5a338001acba30f7b717c7507e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marvin=20L=C3=B6bel?= <loebel.marvin@gmail.com>
Date: Sun, 20 Jan 2013 21:28:12 +0100
Subject: [PATCH] Added char::from_digit(), char::is_digit_radix() and an
 argument check to char::to_digit().

---
 src/libcore/char.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index b656879e7a4..8f1f0b3666b 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -118,6 +118,26 @@ pub pure fn is_digit(c: char) -> bool {
         unicode::general_category::No(c);
 }
 
+/**
+ * Checks if a character parses as a numeric digit in the given radix.
+ * Compared to `is_digit()`, this function only recognizes the ascii
+ * characters `0-9`, `a-z` and `A-Z`.
+ *
+ * Returns `true` if `c` is a valid digit under `radix`, and `false`
+ * otherwise.
+ *
+ * Fails if given a `radix` > 36.
+ *
+ * Note: This just wraps `to_digit()`.
+ */
+#[inline(always)]
+pub pure fn is_digit_radix(c: char, radix: uint) -> bool {
+    match to_digit(c, radix) {
+        Some(_) => true,
+        None    => false
+    }
+}
+
 /**
  * Convert a char to the corresponding digit.
  *
@@ -127,9 +147,15 @@ pub pure fn is_digit(c: char) -> bool {
  * between 0 and 9. If `c` is 'a' or 'A', 10. If `c` is
  * 'b' or 'B', 11, etc. Returns none if the char does not
  * refer to a digit in the given radix.
+ *
+ * # Failure
+ * Fails if given a `radix` outside the range `[0..36]`.
  */
 #[inline]
 pub pure fn to_digit(c: char, radix: uint) -> Option<uint> {
+    if radix > 36 {
+        fail fmt!("to_digit: radix %? is to high (maximum 36)", radix)
+    }
     let val = match c {
       '0' .. '9' => c as uint - ('0' as uint),
       'a' .. 'z' => c as uint + 10u - ('a' as uint),
@@ -140,6 +166,30 @@ pub pure fn to_digit(c: char, radix: uint) -> Option<uint> {
     else { None }
 }
 
+/**
+ * Converts a number to the ascii character representing it.
+ *
+ * Returns `Some(char)` if `num` represents one digit under `radix`,
+ * using one character of `0-9` or `a-z`, or `None` if it doesn't.
+ *
+ * Fails if given an `radix` > 36.
+ */
+#[inline]
+pub pure fn from_digit(num: uint, radix: uint) -> Option<char> {
+    if radix > 36 {
+        fail fmt!("from_digit: radix %? is to high (maximum 36)", num)
+    }
+    if num < radix {
+        if num < 10 {
+            Some(('0' as uint + num) as char)
+        } else {
+            Some(('a' as uint + num - 10u) as char)
+        }
+    } else {
+        None
+    }
+}
+
 /**
  * Return the hexadecimal unicode escape of a char.
  *