#![no_std]
#![feature(coerce_unsized)]
#![feature(layout_for_ptr)]
#![feature(maybe_uninit_extra)]
#![feature(maybe_uninit_ref)]
#![feature(maybe_uninit_slice)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(unsize)]
#![doc(html_root_url = "https://docs.rs/pebble/0.0.1")]
#![warn(clippy::pedantic)]
#![allow(clippy::match_bool)]
#![allow(clippy::module_name_repetitions)]
use core::{
future::Future,
intrinsics::drop_in_place,
marker::{PhantomData, Unsize},
mem::{size_of_val_raw, ManuallyDrop, MaybeUninit},
ops::{CoerceUnsized, Deref, DerefMut},
pin::Pin,
str,
task::{Context, Poll},
};
use pebble_sys::standard_c::memory::free;
use standard_c::{
memory::{calloc, malloc, malloc_buffer_uninit, memcpy_uninit},
CStr, Heap,
};
pub mod foundation;
pub mod graphics;
pub mod standard_c;
pub mod user_interface;
trait SpecialDrop {
fn special_drop(&mut self);
}
pub struct Box<'a, T: ?Sized>(&'a mut T);
impl<'a, T> Box<'a, T> {
pub fn new(value: T) -> Result<Self, T> {
match malloc::<T>() {
Ok(uninit) => Ok(Self(uninit.write(value))),
Err(()) => Err(value),
}
}
#[must_use]
pub fn into_inner(r#box: Self) -> T {
let value;
unsafe {
let mem = Box::leak(r#box) as *mut T;
value = mem.read();
free(&mut *(mem as *mut _));
}
value
}
}
impl<'a> Box<'a, [MaybeUninit<u8>]> {
pub fn new_buffer_uninit(len: usize) -> Result<Self, ()> {
let mem = malloc_buffer_uninit(len)?;
Ok(Self(mem))
}
#[must_use]
pub fn assume_init(r#box: Self) -> Box<'a, [u8]> {
unsafe { Box::from_raw(MaybeUninit::slice_assume_init_mut(Box::leak(r#box))) }
}
}
impl<'a, T: ?Sized> Drop for Box<'a, T> {
fn drop(&mut self) {
unsafe {
let ptr = self.0 as *mut T;
drop_in_place(ptr);
match size_of_val_raw(ptr) {
0 => (),
_ => free(&mut *(ptr as *mut _)),
};
}
}
}
impl<'a, T: ?Sized> Box<'a, T> {
#[must_use = "If the Box instance is not reassembled later, a memory leak occurs."]
pub fn leak(r#box: Self) -> &'a mut T
where
T: 'a,
{
unsafe { &mut *(ManuallyDrop::new(r#box).deref_mut().0 as *mut T) }
}
pub unsafe fn from_raw(raw: &'a mut T) -> Self {
Self(raw)
}
#[must_use]
pub unsafe fn downcast_unchecked<U: Unsize<T>>(r#box: Self) -> Box<'a, U> {
Box::from_raw(&mut *(Box::leak(r#box) as *mut _ as *mut U))
}
}
impl<'a, T: ?Sized> Deref for Box<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<'a, T: ?Sized> DerefMut for Box<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0
}
}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<'a, U>> for Box<'a, T> {}
impl<'a, T: ?Sized> Unpin for Box<'a, T> {}
impl<'a, F: ?Sized + Future + Unpin> Future for Box<'a, F> {
type Output = F::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
F::poll(Pin::new(&mut *self), cx)
}
}
impl Box<'static, CStr<Heap>> {
pub fn clone_to_c_str(value: &str) -> Result<Self, ()> {
let mem = calloc::<u8>(value.len() + 1)?;
unsafe {
memcpy_uninit(&mut mem[..value.len()], value.as_bytes());
mem[value.len()].write(0);
let slice = MaybeUninit::slice_assume_init_mut(mem);
let str = str::from_utf8_unchecked_mut(slice);
let c_str = CStr::from_zero_terminated_unchecked_mut(str);
Ok(Self::from_raw(c_str))
}
}
}
struct Handle<'a, T: 'a + ?Sized>(*mut T, PhantomData<&'a mut T>);
impl<'a, T: 'a + ?Sized> Handle<'a, T> {
pub fn new(exclusive_handle: &'a mut T) -> Self {
Self(exclusive_handle as *mut T, PhantomData)
}
pub fn unwrap(self) -> &'a mut T {
unsafe { &mut *self.0 }
}
#[allow(clippy::mut_from_ref)]
pub unsafe fn as_mut_unchecked(&self) -> &mut T {
&mut *self.0
}
pub unsafe fn duplicate(&self) -> Self {
Self(self.0, self.1)
}
}
impl<'a, T: ?Sized> Deref for Handle<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0 }
}
}
impl<'a, T: ?Sized> DerefMut for Handle<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.0 }
}
}