/src/util.rs
#![allow(dead_code)]
use crate::console::get_global_console;

pub fn dec_digit(n: u32) -> u8 {
    b'0' + (n % 10) as u8
}

pub fn hex_digit(n: u32) -> u8 {
    let mut n = (n & 0xF) as u8;

    if n > 9 {
        n += 7;
    }

    b'0' + n
}

#[test]
fn test_hex_digits() {
    assert!(hex_digit(0) == b'0');
    assert!(hex_digit(10) == b'A');
}

pub fn format_int_dec(n: u32, buf: &mut [u8]) -> usize {
    if n == 0 {
        buf[buf.len() - 1] = b'0';
        return 1;
    }

    let mut n = n;
    let mut c = buf.len() - 1;
    loop {
        buf[c] = dec_digit(n);
        n /= 10;
        if c == 0 || n == 0 {
            break;
        }
        c -= 1;
    }

    buf.len() - c
}

#[test]
fn test_format_int_dec() {
    let mut buf = [0u8; 9];

    let n = format_int_dec(0, &mut buf);
    assert!(n == 1);
    assert!(buf[8] == b'0');

    let n = format_int_dec(255, &mut buf);
    assert!(n == 3);
    assert!(buf[6..] == [b'2', b'5', b'5']);

    let n = format_int_dec(0x20000000, &mut buf);
    assert!(n == 9);
    assert!(buf == "536870912".as_bytes());
}

pub fn format_int_hex(n: u32, buf: &mut[u8]) -> usize {
    if n == 0 {
        buf[buf.len() - 1] = b'0';
        return 1;
    }

    let mut n = n;
    let mut c = buf.len() - 1;
    loop {
        buf[c] = hex_digit(n);
        n >>= 4;
        if c == 0 || n == 0 {
            break;
        }
        c -= 1;
    }

    buf.len() - c
}

#[test]
fn test_format_int_hex() {
    let mut buf = [0u8; 8];

    let n = format_int_hex(0, &mut buf);
    assert!(n == 1);
    assert!(buf[7] == b'0');

    let n = format_int_hex(0x20000000, &mut buf);
    assert!(n == 8);
    assert!(buf == "20000000".as_bytes());
}

pub fn print_hex<T: Into<u32>>(v: T) {
    let v: u32 = v.into();
    let console = get_global_console();
    let mut buf = [0u8; 8];

    let n = format_int_hex(v, &mut buf);
    console.write(&buf[8 - n..]);
}

pub fn print_hex_padded<T: Into<u32>>(v: T, digits: usize) {
    let v: u32 = v.into();
    let console = get_global_console();
    let mut buf = [b'0'; 8];

    format_int_hex(v, &mut buf);
    console.write(&buf[8 - digits..]);
}

pub fn print_dec<T: Into<u32>>(v: T) {
    let v: u32 = v.into();
    let console = get_global_console();
    let mut buf = [0u8; 10];

    let n = format_int_dec(v, &mut buf);
    console.write(&buf[10 - n..]);
}