irid-std 0.3.1

A replacement for std when running without a filesystem on the irid kernel
Documentation
use core::{convert::Infallible, fmt::{Debug, Display}, marker::PhantomData, ops::{Deref, DerefMut}};

use irid_syscall::ffi::thread::syscall_yield;
use spin::{RelaxStrategy, Spin, mutex::{SpinMutex, SpinMutexGuard}};

type Strategy = Spin;

#[derive(Debug, Default)]
pub struct Mutex<T: ?Sized> {
    lock: SpinMutex<T, Strategy>    
}

impl <T> From<T> for Mutex<T> {
    fn from(value: T) -> Self {
        Self::new(value)
    }
}

unsafe impl <T: ?Sized + Send> Send for Mutex<T> {
}

unsafe impl <T: ?Sized + Send> Sync for Mutex<T> {
}

impl <T> Mutex<T> {
    pub const fn new(value: T) -> Self {
        Self {
            lock: SpinMutex::new(value)
        }
    }
} 

impl <T: ?Sized> Mutex<T> {
    pub fn lock(&self) -> Result<MutexGuard<'_, T>, PoisonError<T>> {
        Ok(MutexGuard { guard: self.lock.lock() })
    }
    
    pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError<T>> {
        if let Some(guard) = self.lock.try_lock() {
            Ok(MutexGuard { guard })
        } else {
            Err(TryLockError::WouldBlock)
        }
    }

    pub fn is_poisoned(&self) -> bool {
        false
    }

    pub fn clear_poison(&self) {
    }

    pub fn into_inner(self) -> Result<T, PoisonError<T>> where T: Sized {
        Ok(self.lock.into_inner())
    }

    pub fn get_mut(&mut self) -> Result<&mut T, PoisonError<T>> {
        Ok(self.lock.get_mut())
    }
}

#[derive(Debug)]
pub struct MutexGuard<'a, T: ?Sized> {
    guard: SpinMutexGuard<'a, T, Strategy>
}

impl <'a, T: Display> Display for MutexGuard<'a, T> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", &*self.guard)
    }
} 

unsafe impl <'a, T: ?Sized + Send> Sync for MutexGuard<'a, T> {
}

impl <'a, T: ?Sized> !Send for MutexGuard<'a, T> {
}

impl <'a, T: ?Sized> Deref for MutexGuard<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &*self.guard
    }
}

impl <'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut *self.guard
    }
}

pub struct PoisonError<T: ?Sized> {
    value: PhantomData<T>,
    _cannot_construct: Infallible
}

impl <T: ?Sized> Debug for PoisonError<T> {
    fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        unreachable!("cannot debug a type that can never be constructed")
    }
}

pub(crate) struct Yield;

impl RelaxStrategy for Yield {
    fn relax() {
        syscall_yield()
    }
}

pub enum TryLockError<T: ?Sized> {
    Poisoned(PoisonError<T>),
    WouldBlock
}