const_parse/
lib.rs

1#![no_std]
2
3//! Provides `const fn` for parsing.
4
5/// Parses the input into a `u128` value.
6///
7/// * If the input string is empty, the output is 0.
8/// * If the input string is exclusively decimal ASCII digits that spell a
9///   `u128` value then the output will be that value.
10/// * Otherwise the output is an unspecified value. In this case, differing
11///   input strings are *likely* to produce different output values. Think of it
12///   as a very bad hash function. Use it in your roguelikes to turn the
13///   player's name into a PRNG seed, or something like that.
14pub const fn parse_u128(input_string: &str) -> u128 {
15  let bytes = input_string.as_bytes();
16  let len = bytes.len();
17  let mut index = 0_usize;
18  let mut total = 0_u128;
19  while index < len {
20    total = total.wrapping_mul(10);
21    let u = bytes[index].wrapping_sub(b'0') as u128;
22    total = total.wrapping_add(u);
23    //
24    index += 1;
25  }
26  total
27}
28
29#[cfg(test)]
30mod tests {
31  extern crate std;
32
33  use super::*;
34
35  #[test]
36  fn test_parse_u128() {
37    assert_eq!(parse_u128("0"), 0);
38    assert_eq!(parse_u128("12"), 12);
39    assert_eq!(parse_u128("1234567890"), 1234567890);
40    assert_eq!(parse_u128(&std::format!("{}", u128::MAX)), u128::MAX);
41
42    // here we're just checking that large input strings won't wrap into a panic
43    let big = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
44    let mut s = std::string::String::new();
45    (0..20).for_each(|_| s += big);
46    parse_u128(&s);
47  }
48}