#![no_std]
#![feature(doc_cfg)]
#![feature(never_type)]
extern crate alloc;
use core::marker::PhantomData;
use core::ops::Deref;
use derive_where::derive_where;
use wasefire_error::Code;
pub use wasefire_error::Error;
pub mod applet;
#[cfg(feature = "api-button")]
pub mod button;
#[cfg(feature = "api-clock")]
pub mod clock;
#[cfg(feature = "internal-api-crypto")]
pub mod crypto;
pub mod debug;
#[cfg(feature = "internal-api-fingerprint")]
pub mod fingerprint;
#[cfg(feature = "api-gpio")]
pub mod gpio;
#[cfg(feature = "api-led")]
pub mod led;
pub mod platform;
#[cfg(feature = "api-rng")]
pub mod rng;
#[cfg(feature = "api-timer")]
pub mod timer;
pub mod transfer;
#[cfg(feature = "api-uart")]
pub mod uart;
#[cfg(feature = "internal-api-usb")]
pub mod usb;
#[cfg(feature = "api-vendor")]
pub mod vendor;
pub trait Api: Send + 'static {
fn try_event() -> Option<Event<Self>>;
fn wait_event() -> Event<Self>;
type Applet: applet::Api;
#[cfg(feature = "api-button")]
type Button: button::Api;
#[cfg(feature = "api-clock")]
type Clock: clock::Api;
#[cfg(feature = "internal-api-crypto")]
type Crypto: crypto::Api;
type Debug: debug::Api;
#[cfg(feature = "internal-api-fingerprint")]
type Fingerprint: fingerprint::Api;
#[cfg(feature = "api-gpio")]
type Gpio: gpio::Api;
#[cfg(feature = "api-led")]
type Led: led::Api;
type Platform: platform::Api;
#[cfg(feature = "api-rng")]
type Rng: rng::Api;
#[cfg(feature = "api-storage")]
type Storage: Singleton + wasefire_store::Storage + Send;
#[cfg(feature = "api-timer")]
type Timer: timer::Api;
#[cfg(feature = "api-uart")]
type Uart: uart::Api;
#[cfg(feature = "internal-api-usb")]
type Usb: usb::Api;
#[cfg(feature = "api-vendor")]
type Vendor: vendor::Api;
}
pub trait Support<Value> {
const SUPPORT: Value;
}
pub trait Supported {}
pub trait Singleton: Sized {
fn take() -> Option<Self>;
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive_where(Debug, PartialEq, Eq)]
pub enum Event<B: Api + ?Sized> {
#[cfg(feature = "api-button")]
Button(button::Event<B>),
#[cfg(feature = "internal-api-fingerprint")]
Fingerprint(fingerprint::Event),
#[cfg(feature = "api-gpio")]
Gpio(gpio::Event<B>),
Platform(platform::Event),
#[cfg(feature = "api-timer")]
Timer(timer::Event<B>),
#[cfg(feature = "api-uart")]
Uart(uart::Event<B>),
#[cfg(feature = "internal-api-usb")]
Usb(usb::Event),
#[cfg(feature = "api-vendor")]
Vendor(vendor::Event<B>),
Impossible(Impossible<B>),
}
#[derive_where(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Impossible<B: Api + ?Sized>(!, PhantomData<B>);
#[cfg(feature = "defmt")]
impl<B: Api + ?Sized> defmt::Format for Impossible<B> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "Impossible");
}
}
impl<B: Api + ?Sized> Impossible<B> {
pub fn unreachable(&self) -> ! {
match self.0 {}
}
}
pub type Applet<B> = <B as Api>::Applet;
#[cfg(feature = "api-button")]
pub type Button<B> = <B as Api>::Button;
#[cfg(feature = "api-clock")]
pub type Clock<B> = <B as Api>::Clock;
#[cfg(feature = "internal-api-crypto")]
pub type Crypto<B> = <B as Api>::Crypto;
pub type Debug<B> = <B as Api>::Debug;
#[cfg(feature = "internal-api-fingerprint")]
pub type Fingerprint<B> = <B as Api>::Fingerprint;
#[cfg(feature = "api-gpio")]
pub type Gpio<B> = <B as Api>::Gpio;
#[cfg(feature = "api-led")]
pub type Led<B> = <B as Api>::Led;
pub type Platform<B> = <B as Api>::Platform;
#[cfg(feature = "api-rng")]
pub type Rng<B> = <B as Api>::Rng;
#[cfg(feature = "api-storage")]
pub type Storage<B> = <B as Api>::Storage;
#[cfg(feature = "api-timer")]
pub type Timer<B> = <B as Api>::Timer;
#[cfg(feature = "api-uart")]
pub type Uart<B> = <B as Api>::Uart;
#[cfg(feature = "internal-api-usb")]
pub type Usb<B> = <B as Api>::Usb;
#[cfg(feature = "api-vendor")]
pub type Vendor<B> = <B as Api>::Vendor;
#[derive_where(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Id<T: Support<usize> + ?Sized> {
value: usize,
count: PhantomData<T>,
}
#[cfg(feature = "defmt")]
impl<T: Support<usize> + ?Sized> defmt::Format for Id<T> {
fn format(&self, fmt: defmt::Formatter) {
self.value.format(fmt)
}
}
impl<T: Support<usize>> Id<T> {
pub fn new(value: usize) -> Result<Self, Error> {
match value < T::SUPPORT {
true => Ok(Self { value, count: PhantomData }),
false => Err(Error::user(Code::OutOfBounds)),
}
}
}
impl<T: Support<usize>> Deref for Id<T> {
type Target = usize;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T: Supported> Support<bool> for T {
const SUPPORT: bool = true;
}
pub struct Trap;
#[derive(Default, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Failure(u32);
impl Failure {
pub const TRAP: Self = Failure(0x100_0000);
pub fn split(self) -> Option<Error> {
if self == Self::TRAP {
return None;
}
Some(unsafe { core::mem::transmute::<u32, Error>(self.0) })
}
}
impl From<Trap> for Failure {
fn from(Trap: Trap) -> Self {
Failure::TRAP
}
}
impl From<Error> for Failure {
fn from(value: Error) -> Self {
Failure(unsafe { core::mem::transmute::<Error, u32>(value) })
}
}