#![no_std]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "alloc")]
use core::fmt::Debug;
use core::mem;
use util::TransmutableFrom;
pub mod prelude;
pub mod util;
#[derive(Clone, Copy)]
pub struct Point {
pub x: u8,
pub y: u8,
}
pub const NUM_CHARS: u8 = 44;
pub const NUM_BUTTON_CHARS: u8 = 18;
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "alloc", derive(Debug))]
#[cfg_attr(feature = "std", derive(Hash))]
#[repr(u8)]
pub enum Character {
Zero = 0,
One = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Plus = 10,
Minus = 11,
Multiply = 12,
Slash = 13,
Caret = 14,
OpenParen = 15,
CloseParen = 16,
Dot = 17,
A = 18,
B = 19,
C = 20,
D = 21,
E = 22,
F = 23,
G = 24,
H = 25,
I = 26,
J = 27,
K = 28,
L = 29,
M = 30,
N = 31,
O = 32,
P = 33,
Q = 34,
R = 35,
S = 36,
T = 37,
U = 38,
V = 39,
W = 40,
X = 41,
Y = 42,
Z = 43,
}
pub const NUM_ECHARS: u8 = 2;
#[derive(Clone, Copy)]
#[repr(u8)]
pub enum ExtendedCharacter {
Cursor = NUM_CHARS,
Space,
}
#[derive(Clone, Copy)]
#[repr(C)]
pub union DrawableCharacter {
pub character: Character,
pub extended_character: ExtendedCharacter,
}
impl DrawableCharacter {
#[inline]
pub const fn get(self) -> GetDrawableCharacter {
let raw_self: u8 = self.id();
if raw_self >= NUM_CHARS {
GetDrawableCharacter::ExtendedCharacter(unsafe { self.extended_character })
} else {
GetDrawableCharacter::Character(unsafe { self.character })
}
}
pub const fn id(self) -> u8 {
unsafe { mem::transmute(self) }
}
}
impl PartialEq for DrawableCharacter {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl Eq for DrawableCharacter {}
unsafe impl TransmutableFrom<Character> for DrawableCharacter {
fn transmute_from(val: Character) -> Self {
val.into()
}
}
unsafe impl TransmutableFrom<ExtendedCharacter> for DrawableCharacter {
fn transmute_from(val: ExtendedCharacter) -> Self {
val.into()
}
}
impl From<Character> for DrawableCharacter {
fn from(character: Character) -> Self {
Self { character }
}
}
impl From<ExtendedCharacter> for DrawableCharacter {
fn from(extended_character: ExtendedCharacter) -> Self {
Self { extended_character }
}
}
impl AsRef<DrawableCharacter> for Character {
fn as_ref(&self) -> &DrawableCharacter {
unsafe { &*(self as *const Character as *const DrawableCharacter) }
}
}
impl AsMut<DrawableCharacter> for Character {
fn as_mut(&mut self) -> &mut DrawableCharacter {
unsafe { &mut *(self as *mut Character as *mut DrawableCharacter) }
}
}
impl AsRef<DrawableCharacter> for ExtendedCharacter {
fn as_ref(&self) -> &DrawableCharacter {
unsafe { &*(self as *const ExtendedCharacter as *const DrawableCharacter) }
}
}
impl AsMut<DrawableCharacter> for ExtendedCharacter {
fn as_mut(&mut self) -> &mut DrawableCharacter {
unsafe { &mut *(self as *mut ExtendedCharacter as *mut DrawableCharacter) }
}
}
pub enum GetDrawableCharacter {
Character(Character),
ExtendedCharacter(ExtendedCharacter),
}
pub const NUM_META_BUTTONS: u8 = 7;
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "alloc", derive(Debug))]
#[cfg_attr(feature = "std", derive(Hash))]
#[repr(u8)]
pub enum MetaButton {
Left = NUM_BUTTON_CHARS,
Right,
Up,
Down,
Back,
Enter,
Clear,
Alt,
Menu,
}
#[derive(Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Hash))]
#[repr(transparent)]
pub struct Button(u8);
#[cfg(feature = "alloc")]
impl Debug for Button {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.get().fmt(f)
}
}
#[cfg_attr(feature = "alloc", derive(Debug))]
#[cfg_attr(feature = "std", derive(Hash))]
#[derive(Clone, Copy)]
pub enum GetButton {
Character(Character),
Meta(MetaButton),
}
impl Button {
#[inline]
pub fn get(self) -> GetButton {
if self.0 < NUM_BUTTON_CHARS {
let character: Character = unsafe { mem::transmute(self.0) };
GetButton::Character(character)
} else {
let meta_button: MetaButton = unsafe { mem::transmute(self.0) };
GetButton::Meta(meta_button)
}
}
pub fn from_raw(raw: u8) -> Option<Self> {
if raw < NUM_BUTTON_CHARS + NUM_META_BUTTONS {
Some(unsafe { Self::from_raw_unchecked(raw) })
} else {
None
}
}
pub unsafe fn from_raw_unchecked(raw: u8) -> Self {
Self(raw)
}
}
impl From<MetaButton> for Button {
fn from(value: MetaButton) -> Self {
Self(value as u8)
}
}
impl From<Character> for Button {
fn from(value: Character) -> Self {
let raw = value as u8;
if raw < NUM_BUTTON_CHARS {
Self(value as u8)
} else {
panic!("Attempted to convert non-button character into a button");
}
}
}
impl Character {
#[inline(always)]
pub fn from_digit(digit: u8) -> Option<Self> {
if digit < 10 {
unsafe { Some(mem::transmute::<u8, Self>(digit)) }
} else {
None
}
}
}