irid-std 0.3.1

A replacement for std when running without a filesystem on the irid kernel
Documentation
use core::ops::Deref;

use crate::sync::Mutex;

pub struct LazyLock<T> {
    data: Mutex<Option<T>>,
    create_new: fn() -> T,
}

unsafe impl <T> Send for LazyLock<T> {
}

unsafe impl <T> Sync for LazyLock<T> {
}

impl <T> LazyLock<T> {
    pub const fn new(f: fn() -> T) -> Self {
        Self {
            data: Mutex::new(None),
            create_new: f,
        }
    }
}

impl <T> Deref for LazyLock<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        if let Some(value) = self.data.lock().expect("failed to lock lazy lock").as_ref() {
            unsafe { (value as *const T).as_ref_unchecked() }
        } else {
            let mut guard = self.data.lock().expect("failed to lock lazy lock");

            *guard = Some((self.create_new)());

            unsafe { (guard.as_ref().expect("no item in lazylock") as *const T).as_ref_unchecked() }
        }
    }
}