graphics/
screen.rs

1use core::mem::{size_of, transmute};
2
3use crate::{Area, Point, RenderingColor};
4
5pub struct ScreenWriteData<'a> {
6    area: Area,
7    buffer: &'a [RenderingColor],
8}
9
10impl<'a> ScreenWriteData<'a> {
11    pub fn new(area: Area, buffer: &'a [RenderingColor]) -> Self {
12        Self { area, buffer }
13    }
14}
15
16impl AsRef<[u8]> for ScreenWriteData<'_> {
17    fn as_ref(&self) -> &[u8] {
18        unsafe { core::slice::from_raw_parts(self as *const _ as *const u8, size_of::<Self>()) }
19    }
20}
21
22impl TryFrom<&[u8]> for &ScreenWriteData<'_> {
23    type Error = ();
24
25    /// This function is used to convert a buffer of bytes to a struct.
26    ///
27    /// # Arguments
28    ///
29    /// * `Value` - A buffer of bytes.
30    ///
31    /// # Errors
32    ///
33    /// This function will return an error if the size of the buffer is not the same as the size of the struct.
34    ///
35    /// # Safety
36    ///
37    /// This function is unsafe because it dereferences a raw pointer.
38    ///
39    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
40        if value.len() != size_of::<ScreenWriteData>() {
41            return Err(());
42        }
43
44        if !(value.as_ptr() as usize).is_multiple_of(align_of::<ScreenWriteData>()) {
45            return Err(());
46        }
47
48        #[allow(clippy::transmute_ptr_to_ref)]
49        Ok(unsafe { transmute::<*const u8, Self>(value.as_ptr()) })
50    }
51}
52
53impl ScreenWriteData<'_> {
54    pub fn get_area(&self) -> Area {
55        self.area
56    }
57
58    pub fn get_buffer(&self) -> &[RenderingColor] {
59        self.buffer
60    }
61}
62
63#[derive(Clone, Copy, Debug, PartialEq, Eq)]
64#[repr(transparent)]
65pub struct ScreenReadData(Point);
66
67impl Default for ScreenReadData {
68    fn default() -> Self {
69        Self(Point::new(0, 0))
70    }
71}
72
73impl ScreenReadData {
74    pub fn get_resolution(&self) -> Point {
75        self.0
76    }
77
78    pub fn set_resolution(&mut self, value: Point) {
79        self.0 = value;
80    }
81}
82
83impl AsMut<[u8]> for ScreenReadData {
84    fn as_mut(&mut self) -> &mut [u8] {
85        unsafe { core::slice::from_raw_parts_mut(self as *mut _ as *mut u8, size_of::<Self>()) }
86    }
87}
88
89impl TryFrom<&mut [u8]> for &mut ScreenReadData {
90    type Error = ();
91
92    fn try_from(value: &mut [u8]) -> Result<Self, Self::Error> {
93        if value.len() != size_of::<ScreenReadData>() {
94            return Err(());
95        }
96        if !(value.as_ptr() as usize).is_multiple_of(align_of::<ScreenReadData>()) {
97            return Err(());
98        }
99
100        #[allow(clippy::transmute_ptr_to_ref)]
101        Ok(unsafe { transmute::<*mut u8, Self>(value.as_mut_ptr()) })
102    }
103}