osom_lib_arrays/dynamic_array/inline_dynamic_array/
mutable_inline_array.rs1#![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}