pub fn to_base_36<N: Into<u128>>(number: N) -> String {
const RADIX: u32 = 36;
let mut number = number.into();
if number < RADIX as u128 {
return char::from_digit(number as u32, RADIX)
.expect("35 and under is always valid")
.to_string();
}
let mut buffer = String::with_capacity(25);
while number > 0 {
buffer.push(
char::from_digit((number % RADIX as u128) as u32, RADIX)
.expect("Modulo radix always yields a valid number"),
);
number /= RADIX as u128;
}
unsafe {
buffer.as_mut_vec().reverse();
}
buffer
}
pub trait ToBase36 {
fn to_base_36(self) -> String;
}
impl<N> ToBase36 for N
where
N: Into<u128>,
{
fn to_base_36(self) -> String {
to_base_36(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn doesnt_panic(n: u128) {
to_base_36(n);
}
#[test]
fn expected_output(n: u128) {
let val = to_base_36(n);
assert_eq!(
&format!("{}", radix_fmt::radix_36(n)),
&val,
);
assert_eq!(
&num::bigint::BigUint::from_bytes_be(&n.to_be_bytes()).to_str_radix(36),
&val
)
}
}
}