Skip to main content

osom_lib_arrays/dynamic_array/inline_dynamic_array/
mutable_inline_array.rs

1#![allow(clippy::cast_possible_truncation)]
2
3use osom_lib_alloc::traits::Allocator;
4use osom_lib_primitives::length::Length;
5use osom_lib_try_clone::TryClone;
6
7use crate::{
8    errors::{ArrayError, ArrayIsEmptyError, ArrayTryCloneError},
9    traits::MutableArray,
10};
11
12use super::InlineDynamicArray;
13
14impl<const TCAPACITY: usize, T, TAllocator> MutableArray<T> for InlineDynamicArray<TCAPACITY, T, TAllocator>
15where
16    T: Sized,
17    TAllocator: Allocator,
18{
19    fn try_push_array<const TSIZE: usize>(&mut self, arr: [T; TSIZE]) -> Result<(), ArrayError> {
20        let length = self.size.as_usize();
21        let Some(new_length) = length.checked_add(TSIZE) else {
22            return Err(ArrayError::LengthLimitExceeded);
23        };
24
25        if new_length > Length::MAX_LENGTH.as_usize() {
26            return Err(ArrayError::LengthLimitExceeded);
27        }
28
29        let new_length = new_length as u32;
30
31        self.reserve_if_needed(new_length)?;
32
33        unsafe {
34            let current_end = self.current_ptr_mut().add(length);
35            let mut arr = arr;
36            let arr_ptr = arr.as_mut_ptr();
37            current_end.copy_from_nonoverlapping(arr_ptr, TSIZE);
38            core::mem::forget(arr);
39            self.size = Length::new_unchecked(new_length);
40        }
41
42        Ok(())
43    }
44
45    fn try_push_slice(&mut self, slice: &[T]) -> Result<(), ArrayTryCloneError>
46    where
47        T: TryClone,
48    {
49        let length = self.size.as_usize();
50        let Some(new_length) = length.checked_add(slice.len()) else {
51            return Err(ArrayError::LengthLimitExceeded.into());
52        };
53
54        if new_length > Length::MAX_LENGTH.as_usize() {
55            return Err(ArrayError::LengthLimitExceeded.into());
56        }
57
58        let new_length = new_length as u32;
59
60        self.reserve_if_needed(new_length)?;
61
62        unsafe {
63            let mut current_end = self.current_ptr_mut().add(length);
64            let mut slice_val = slice.as_ptr();
65            for _ in 0..slice.len() {
66                let clone = (&*slice_val)
67                    .try_clone()
68                    .map_err(|_| ArrayTryCloneError::ItemCloningError)?;
69                current_end.write(clone);
70                current_end = current_end.add(1);
71                slice_val = slice_val.add(1);
72            }
73            self.size = Length::new_unchecked(new_length);
74        }
75
76        Ok(())
77    }
78
79    fn try_pop(&mut self) -> Result<T, ArrayIsEmptyError> {
80        let len = self.size.as_usize();
81        if len == 0 {
82            return Err(ArrayIsEmptyError);
83        }
84
85        let idx = len - 1;
86        unsafe {
87            self.size = Length::new_unchecked(idx as u32);
88            let ptr = self.current_ptr_mut().add(idx);
89            Ok(ptr.read())
90        }
91    }
92}