1use crate::errors::Result;
2use crate::stringhandle::{StringArray, StringHandle};
3use std::borrow::Cow;
4
5pub struct DataArray<'a, T>
8where
9 [T]: ToOwned<Owned = Vec<T>>,
10{
11 data: Cow<'a, [T]>,
12 sizes: Cow<'a, [i32]>,
13}
14impl<'a, T> DataArray<'a, T>
15where
16 [T]: ToOwned<Owned = Vec<T>>,
17{
18 pub fn new(data: &'a [T], sizes: &'a [i32]) -> DataArray<'a, T> {
20 debug_assert_eq!(sizes.iter().sum::<i32>() as usize, data.len());
21 DataArray {
22 data: Cow::Borrowed(data),
23 sizes: Cow::Borrowed(sizes),
24 }
25 }
26
27 pub(crate) fn new_owned(data: Vec<T>, sizes: Vec<i32>) -> DataArray<'static, T> {
29 debug_assert_eq!(sizes.iter().sum::<i32>() as usize, data.len());
30 DataArray {
31 data: Cow::Owned(data),
32 sizes: Cow::Owned(sizes),
33 }
34 }
35
36 pub fn data(&self) -> &[T] {
38 self.data.as_ref()
39 }
40 pub fn sizes(&self) -> &[i32] {
42 self.sizes.as_ref()
43 }
44
45 pub fn data_mut(&mut self) -> &mut [T] {
46 self.data.to_mut().as_mut()
47 }
48 pub fn sizes_mut(&mut self) -> &mut [i32] {
49 self.sizes.to_mut().as_mut()
50 }
51
52 pub fn iter(&'a self) -> ArrayIter<'a, T> {
54 ArrayIter {
55 sizes: self.sizes.iter(),
56 data: self.data.as_ref(),
57 cursor: 0,
58 }
59 }
60 pub fn iter_mut(&'a mut self) -> ArrayIterMut<'a, T> {
62 ArrayIterMut {
63 sizes: self.sizes.to_mut().iter_mut(),
64 data: self.data.to_mut().as_mut(),
65 cursor: 0,
66 }
67 }
68}
69
70pub struct StringMultiArray {
73 pub(crate) handles: Vec<StringHandle>,
74 pub(crate) sizes: Vec<i32>,
75 pub(crate) session: crate::session::Session,
76}
77
78pub struct ArrayIter<'a, T> {
80 data: &'a [T],
81 sizes: std::slice::Iter<'a, i32>,
82 cursor: usize,
83}
84
85pub struct ArrayIterMut<'a, T> {
87 data: &'a mut [T],
88 sizes: std::slice::IterMut<'a, i32>,
89 cursor: usize,
90}
91
92pub struct MultiArrayIter<'a> {
93 handles: std::slice::Iter<'a, StringHandle>,
94 sizes: std::slice::Iter<'a, i32>,
95 session: &'a crate::session::Session,
96 cursor: usize,
97}
98
99impl<'a, T> Iterator for ArrayIter<'a, T> {
100 type Item = &'a [T];
101
102 fn next(&mut self) -> Option<Self::Item> {
103 match self.sizes.next() {
104 None => None,
105 Some(size) => {
106 let start = self.cursor;
107 let end = self.cursor + (*size as usize);
108 self.cursor = end;
109 Some(unsafe { self.data.get_unchecked(start..end) })
112 }
113 }
114 }
115}
116
117impl<'a, T> Iterator for ArrayIterMut<'a, T> {
118 type Item = &'a mut [T];
119
120 fn next(&mut self) -> Option<Self::Item> {
121 match self.sizes.next() {
122 None => None,
123 Some(size) => {
124 let start = self.cursor;
125 let end = self.cursor + (*size as usize);
126 self.cursor = end;
127 Some(unsafe { &mut *(self.data.get_unchecked_mut(start..end) as *mut [T]) })
130 }
131 }
132 }
133}
134
135impl StringMultiArray {
136 pub fn iter(&self) -> MultiArrayIter<'_> {
137 MultiArrayIter {
138 handles: self.handles.iter(),
139 sizes: self.sizes.iter(),
140 session: &self.session,
141 cursor: 0,
142 }
143 }
144 pub fn flatten(self) -> Result<(Vec<String>, Vec<usize>)> {
146 let mut flat_array = Vec::with_capacity(self.sizes.iter().sum::<i32>() as usize);
147 let mut iter = self.iter();
148 while let Some(Ok(string_array)) = iter.next() {
149 flat_array.extend(string_array.into_iter());
150 }
151 Ok((flat_array, self.sizes.iter().map(|v| *v as usize).collect()))
152 }
153}
154
155impl Iterator for MultiArrayIter<'_> {
156 type Item = Result<StringArray>;
157
158 fn next(&mut self) -> Option<Self::Item> {
159 match self.sizes.next() {
160 None => None,
161 Some(size) => {
162 let start = self.cursor;
163 let end = self.cursor + (*size as usize);
164 self.cursor = end;
165 let handles = &self.handles.as_slice()[start..end];
166 Some(crate::stringhandle::get_string_array(handles, self.session))
167 }
168 }
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[test]
177 fn data_array_iter() {
178 let ar = DataArray::new_owned(vec![1, 2, 3, 4, 5, 6], vec![2, 1, 3]);
179 let mut iter = ar.iter();
180 assert_eq!(iter.next(), Some([1, 2].as_slice()));
181 assert_eq!(iter.next(), Some([3].as_slice()));
182 assert_eq!(iter.next(), Some([4, 5, 6].as_slice()));
183 }
184
185 #[test]
186 fn data_array_mutate() {
187 let mut ar = DataArray::new(&[1, 2, 3, 4, 5, 6], &[2, 1, 3]);
188 let mut iter = ar.iter_mut().map(|v| {
189 v.iter_mut().for_each(|v| *v *= 2);
190 v
191 });
192 assert_eq!(iter.next(), Some([2, 4].as_mut_slice()));
193 assert_eq!(iter.next(), Some([6].as_mut_slice()));
194 assert_eq!(iter.next(), Some([8, 10, 12].as_mut_slice()));
195 }
196}