/src/console/mod.rs
use core::fmt;

mod key;
pub mod serial;
mod traits;
mod interfaces;

use crate::console::serial::SerialTerminal;

pub use key::*;
pub use traits::*;
pub use interfaces::*;

#[link_section = ".kgbss"]
static mut G_CONSOLE: Option<Console> = None;

pub fn get_global_console() -> &'static mut Console {
    unsafe {
        core::intrinsics::transmute(&mut G_CONSOLE)
    }
}

pub struct Console {
    terminal: SerialTerminal,
}

impl Console {
    pub fn new(terminal: SerialTerminal) -> Console {
        Console {
            terminal,
        }
    }

    pub fn readkey(&mut self) -> Option<Key> {
        self.terminal.readkey()
    }

    pub fn readline(&mut self, buf: &mut [u8]) -> usize {
        self.terminal.readline(buf)
    }

    pub fn discard(&mut self) {
        self.terminal.discard();
    }

    pub fn pos(&mut self, x: usize, y: usize) {
        self.terminal.pos(x, y);
    }

    pub fn writeb(&mut self, b: u8) {
        self.terminal.writeb(b);
    }

    pub fn write<T: AsRef<[u8]>>(&mut self, a: T) {
        self.terminal.write(a);
    }

    pub fn clear(&mut self) {
        self.terminal.clear();
    }

    pub fn handle_interrupt(&mut self) {
        self.terminal.handle_interrupt();
    }
}

impl fmt::Write for Console {
    fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
        self.write(s);
        Ok(())
    }
}