human-binary 0.1.0

A crate to convert numbers to a human-usable binary format
Documentation
pub fn add(left: u64, right: u64) -> u64 {
    left + right
}

const WORDS: [&str; 10] = [
    "zero", "one", "two", "four", "hex", "byte", "int", "long", "overlong", "byteplex",
];

pub fn to_binary_string(num: u64, short: bool) -> String {
    if num == 0 {
        return "zero".to_string();
    }
    let mut result = Vec::new();
    recurse(num, &mut result);
    
    if short {
        result.join(" ").replace("two one", "three")
    } else {
        result.join(" ")
    }
}

fn recurse(num: u64, result: &mut Vec<String>) {
    if num == 1 {
        result.push(WORDS[1].to_string());
        return;
    }

    let maxdoublepowerof2 = num.ilog2().ilog2();
    let shift = 2u64.pow(maxdoublepowerof2);

    //split at that bit
    let highbits = num >> shift;
    let lowbits = num & (1 << shift) - 1;

    let power = WORDS[(maxdoublepowerof2 + 2) as usize].to_string();
    if highbits > 1 {
        recurse(highbits, result);
    }

    result.push(power);

    if lowbits > 0 {
        recurse(lowbits, result);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn long_form_works() {
        let result = to_binary_string(123, false);
        assert_eq!(result, "four two one hex two four two one");
    }
    
    #[test]
    fn short_form_works() {
        let result = to_binary_string(123, true);
        assert_eq!(result, "four three hex two four three");
    }
}