Shared/
Mutable_slice.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::{
    fmt::{Debug, Display, Formatter},
    ptr::NonNull,
};

use num::{Num, NumCast, ToPrimitive, Unsigned};

use crate::Error_type;

#[derive(Debug)]
pub struct Mutable_slice_type<'a, T, S = u32>
where
    S: Unsigned + Num + NumCast + PartialOrd + ToPrimitive + Copy,
{
    Data: &'a mut [T],
    Length: &'a mut S,
}

impl<'a, T, S> Mutable_slice_type<'a, T, S>
where
    S: Unsigned + Num + NumCast + Num + PartialOrd + ToPrimitive + Copy,
{
    pub fn From(Slice: NonNull<T>, mut Length: NonNull<S>, Size: S) -> Result<Self, Error_type> {
        let Data: &'a mut [T] = unsafe {
            std::slice::from_raw_parts_mut(
                Slice.as_ptr(),
                Size.to_usize()
                    .ok_or(Error_type::Failed_to_convert_length_to_S)?,
            )
        };

        if unsafe { *Length.as_ref() } > Size {
            return Err(Error_type::Invalid_length);
        }

        Ok(Self {
            Data,
            Length: unsafe { Length.as_mut() },
        })
    }

    pub fn Push(&mut self, Value: T) -> Result<(), Error_type> {
        if self.Get_length() >= self.Get_size() {
            return Err(Error_type::Buffer_too_small);
        }

        self.Data[self.Get_length()] = Value;
        self.Set_length(
            S::from(self.Get_length()).ok_or(Error_type::Failed_to_convert_length_to_S)?
                + S::from(1).unwrap(),
        )
    }

    fn Set_length(&mut self, Length: S) -> Result<(), Error_type> {
        if Length.to_usize().unwrap() > self.Get_size() {
            return Err(Error_type::Invalid_length);
        }

        *self.Length = Length as S;
        Ok(())
    }

    pub fn Clear(&mut self) {
        self.Set_length(S::from(0).unwrap()).unwrap();
    }

    pub fn Is_empty(&self) -> bool {
        self.Get_length() == 0
    }

    pub fn Get_length(&self) -> usize {
        (*self.Length).to_usize().unwrap()
    }

    pub fn Get_size(&self) -> usize {
        self.Data.len()
    }

    pub fn As_slice(&self) -> &[T] {
        &self.Data[..self.Get_length()]
    }
}

impl<T: Debug> Display for Mutable_slice_type<'_, T> {
    fn fmt(&self, Formatter: &mut Formatter<'_>) -> std::fmt::Result {
        write!(Formatter, "{:?}", self.As_slice())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn Test_mutable_slice() {
        let mut Data = [1, 2, 3, 4, 5];
        let mut Length: u32 = 3;

        let Raw_slice = NonNull::new(Data.as_mut_ptr()).unwrap();
        let Length = NonNull::new(&mut Length).unwrap();

        let mut Slice = Mutable_slice_type::From(Raw_slice, Length, 5).unwrap();

        assert_eq!(Slice.Get_length(), 3);
        assert_eq!(Slice.Get_size(), 5);
        assert_eq!(Slice.As_slice(), &[1, 2, 3]);

        Slice.Clear();

        assert_eq!(Slice.Get_length(), 0);
        assert!(Slice.Is_empty());

        Slice.Push(1).unwrap();

        assert_eq!(Slice.Get_length(), 1);
        assert_eq!(Slice.As_slice(), &[1]);

        Slice.Push(2).unwrap();

        assert_eq!(Slice.Get_length(), 2);
        assert_eq!(Slice.As_slice(), &[1, 2]);
    }
}