1use core::{future::Future, mem::transmute, num::NonZeroUsize, pin::Pin};
2
3use alloc::{boxed::Box, string::String};
4
5use crate::Standard;
6
7pub type MainFunction = Box<
8 dyn Fn(
9 Standard,
10 String,
11 )
12 -> Pin<Box<dyn Future<Output = core::result::Result<(), NonZeroUsize>> + 'static>>
13 + 'static,
14>;
15
16pub struct ReadData {
17 main: Option<MainFunction>,
18}
19
20impl ReadData {
21 pub fn new<F>(main: impl Fn(Standard, String) -> F + 'static) -> Self
22 where
23 F: Future<Output = core::result::Result<(), NonZeroUsize>> + 'static,
24 {
25 Self {
26 main: Some(Box::new(move |standard, arguments| {
27 Box::pin(main(standard, arguments))
28 })),
29 }
30 }
31
32 pub const fn new_default() -> [u8; size_of::<Self>()] {
33 [0; size_of::<Self>()]
34 }
35
36 pub const fn get_size(&self) -> usize {
37 size_of::<Self>()
38 }
39
40 pub fn get_main(self) -> Option<MainFunction> {
41 self.main
42 }
43}
44
45impl TryFrom<&mut [u8]> for &mut ReadData {
46 type Error = ();
47
48 fn try_from(value: &mut [u8]) -> core::result::Result<Self, Self::Error> {
49 if value.len() != size_of::<ReadData>() {
50 return Err(());
51 }
52 if !(value.as_ptr() as usize).is_multiple_of(core::mem::align_of::<ReadData>()) {
53 return Err(());
54 }
55
56 #[allow(clippy::transmute_ptr_to_ref)]
57 Ok(unsafe { transmute::<*mut u8, Self>(value.as_mut_ptr()) })
58 }
59}
60
61impl TryFrom<[u8; size_of::<ReadData>()]> for ReadData {
62 type Error = ();
63
64 fn try_from(value: [u8; size_of::<ReadData>()]) -> core::result::Result<Self, Self::Error> {
65 Ok(unsafe { transmute::<[u8; size_of::<ReadData>()], Self>(value) })
66 }
67}
68
69impl AsMut<[u8]> for ReadData {
70 fn as_mut(&mut self) -> &mut [u8] {
71 unsafe { core::slice::from_raw_parts_mut(self as *mut _ as *mut u8, size_of::<Self>()) }
72 }
73}