rttrust 0.1.3

Rust wrapper for rt-thread
Documentation
use super::IpcFlag;
use crate::{
    cstr::RtName,
    ffi::{
        rt_mutex, rt_mutex_create, rt_mutex_delete, rt_mutex_detach, rt_mutex_init,
        rt_mutex_release, rt_mutex_t, rt_mutex_take, rt_object,
    },
    object::Object,
    Result, RtError,
};
use core::{cell::UnsafeCell, marker::PhantomPinned, mem::MaybeUninit, ptr::NonNull};

#[derive(Copy, Clone, Debug)]
pub struct Mutex {
    raw: rt_mutex_t,
}

unsafe impl Send for Mutex {}
unsafe impl Sync for Mutex {}

impl Mutex {
    pub fn create(name: &str, flag: IpcFlag) -> Result<Self> {
        let name: RtName = name.into();
        let result = unsafe { rt_mutex_create(name.into(), flag.into()) };
        if result.is_null() {
            Err(RtError::Error)
        } else {
            Ok(Mutex { raw: result })
        }
    }

    #[inline]
    pub fn delete(self) -> Result<()> {
        let err = unsafe { rt_mutex_delete(self.raw) };
        RtError::from_code_none(err, ())
    }

    #[inline]
    pub fn take(&self, time: i32) -> Result<()> {
        let err = unsafe { rt_mutex_take(self.raw, time) };
        RtError::from_code_none(err, ())
    }

    #[inline]
    pub fn release(&self) -> Result<()> {
        let err = unsafe { rt_mutex_release(self.raw) };
        RtError::from_code_none(err, ())
    }
}

impl Object for Mutex {
    fn get_ptr(&self) -> NonNull<rt_object> {
        NonNull::new(self.raw.cast()).expect("Unexpected null rt_mutex_t")
    }
}

pub struct MutexStatic {
    raw: UnsafeCell<MaybeUninit<rt_mutex>>,
    _pinned: PhantomPinned,
}

unsafe impl Send for MutexStatic {}
unsafe impl Sync for MutexStatic {}

impl MutexStatic {
    pub const fn new() -> Self {
        MutexStatic {
            raw: UnsafeCell::new(core::mem::MaybeUninit::uninit()),
            _pinned: PhantomPinned {},
        }
    }
    pub fn init(&'static self, name: &str, flag: IpcFlag) -> Result<()> {
        let name: RtName = name.into();
        let err = unsafe { rt_mutex_init(self.raw.get().cast(), name.into(), flag.into()) };
        RtError::from_code_none(err, ())
    }

    #[inline]
    pub fn detach(&'static self) -> Result<()> {
        let err = unsafe { rt_mutex_detach(self.raw.get().cast()) };
        RtError::from_code_none(err, ())
    }

    pub fn get(&'static self) -> Mutex {
        Mutex {
            raw: self.raw.get().cast(),
        }
    }
}