osal_rs/
utils.rs

1/***************************************************************************
2 *
3 * osal-rs
4 * Copyright (C) 2023/2026 Antonio Salsi <passy.linux@zresa.it>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 ***************************************************************************/
19
20use core::ffi::{CStr, c_char};
21use core::{ffi::c_void, str::from_utf8_mut};
22use core::fmt::{Debug, Display}; 
23use core::ops::Deref;
24use core::time::Duration;
25use alloc::string::{String, ToString};
26
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28pub enum Error {
29    OutOfMemory,
30    QueueSendTimeout,
31    QueueReceiveTimeout,
32    MutexTimeout,
33    MutexLockFailed,
34    Timeout,
35    QueueFull,
36    StringConversionError,
37    TaskNotFound,
38    InvalidQueueSize,
39    NullPtr,
40    NotFound,
41    OutOfIndex,
42    InvalidType,
43    Unhandled(&'static str)
44}
45
46#[derive(PartialEq, Eq, Clone, Copy, Debug)]
47pub enum CpuRegisterSize {
48    Bit64,
49    Bit32
50}
51
52#[derive(PartialEq, Eq, Clone, Copy, Debug)]
53#[repr(u8)]
54pub enum OsalRsBool {
55    False = 1,
56    True = 0
57}
58
59pub const MAX_DELAY: Duration = Duration::from_millis(usize::MAX as u64);
60
61pub type Result<T, E = Error> = core::result::Result<T, E>;
62
63pub type DoublePtr = *mut *mut c_void;
64pub type Ptr = *mut c_void;
65pub type ConstPtr = *const c_void;
66
67
68pub const fn register_bit_size() -> CpuRegisterSize {
69    if size_of::<usize>() == 8 {
70        CpuRegisterSize::Bit64
71    } else {
72        CpuRegisterSize::Bit32
73    }
74}
75
76#[macro_export]
77macro_rules! from_c_str {
78    ($str:expr) => {
79        unsafe {
80            let c_str = core::ffi::CStr::from_ptr($str);
81            alloc::string::String::from_utf8_lossy(c_str.to_bytes()).to_string()
82        }
83    };
84}
85
86#[macro_export]
87macro_rules! to_cstring {
88    ($s:expr) => {
89        alloc::ffi::CString::new($s.as_str())
90            .map_err(|_| $crate::utils::Error::Unhandled("Failed to convert string to CString"))
91    };
92}
93
94#[macro_export]
95macro_rules! to_c_str {
96    ($s:expr) => {
97        alloc::ffi::CString::new($s.as_ref() as &str).unwrap().as_ptr()
98    };
99}
100
101#[macro_export]
102macro_rules! from_str_to_array {
103    ($str:expr, $buff_name:ident, $buff_size:expr) => {
104        let mut $buff_name = [b' '; $buff_size];
105        let _bytes = $str.as_bytes();
106        let _len = core::cmp::min(_bytes.len(), $buff_size);
107        $buff_name[.._len].copy_from_slice(&_bytes[.._len]);
108    };
109}
110
111#[macro_export]
112macro_rules! thread_extract_param {
113    ($param:expr, $t:ty) => {
114        match $param.as_ref() {
115            Some(p) => {
116                match p.downcast_ref::<$t>() {
117                    Some(value) => value,
118                    None => return Err($crate::utils::Error::InvalidType),
119                }
120            }
121            None => return Err($crate::utils::Error::NullPtr),
122        }
123    };
124}
125
126#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
127pub struct Bytes<const SIZE: usize = 0> (pub [u8; SIZE]);
128
129impl<const SIZE: usize> Deref for Bytes<SIZE> {
130    type Target = [u8; SIZE];
131
132    fn deref(&self) -> &Self::Target {
133        &self.0
134    }
135}
136
137impl<const SIZE: usize> Display for Bytes<SIZE> {
138    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
139        let str = unsafe {
140            CStr::from_ptr(self.0.as_ptr() as *const c_char)
141            .to_str()
142            .unwrap_or("Conversion error")
143        };
144        
145        write!(f, "{}", str.to_string())
146    }
147}
148
149
150impl<const SIZE: usize> Bytes<SIZE> {
151    pub const fn new() -> Self {
152        Self( [0u8; SIZE] )
153    }
154
155    pub fn new_by_str(str: &str) -> Self {
156
157        let mut array = [0u8; SIZE];
158        
159        let mut i = 0usize ;
160        for byte in str.as_bytes() {
161            if i > SIZE - 1{
162                break;
163            }
164            array[i] = *byte;
165            i += 1;
166        }  
167
168        Self( array )
169    }
170
171    pub fn new_by_string(str: &impl ToString) -> Self {
172        Self::new_by_str(&str.to_string())
173    }
174
175    pub fn fill_str(&mut self, dest: &mut str) {
176        match from_utf8_mut(&mut self.0) {
177            Ok(str) => {
178                let len = core::cmp::min(str.len(), dest.len());
179                unsafe {
180                    dest.as_bytes_mut()[..len].copy_from_slice(&str.as_bytes()[..len]);
181                }
182            }
183            Err(_) => todo!(),
184        }
185    }
186}