1use crate::{index::RowIndex, Index2, Jagged};
6
7pub trait JaggedIndex<T> {
9 type Output: Sized;
10
11 fn get(self, array: &Jagged<T>) -> Option<&Self::Output>;
12 fn get_mut(self, array: &mut Jagged<T>) -> Option<&mut Self::Output>;
13}
14
15pub trait JaggedRemove<T> {
16 type Output: Sized;
17 fn remove(self, array: &mut Jagged<T>) -> Self::Output;
18}
19
20impl<T> JaggedIndex<T> for Index2 {
21 type Output = T;
22
23 fn get(self, array: &Jagged<T>) -> Option<&Self::Output> {
24 array.data.get(self.row).and_then(|line| line.get(self.col))
25 }
26
27 fn get_mut(self, array: &mut Jagged<T>) -> Option<&mut Self::Output> {
28 array
29 .data
30 .get_mut(self.row)
31 .and_then(|line| line.get_mut(self.col))
32 }
33}
34
35impl<T> JaggedRemove<T> for Index2 {
36 type Output = T;
37
38 fn remove(self, array: &mut Jagged<T>) -> Self::Output {
39 array.data[self.row].remove(self.col)
40 }
41}
42
43impl<T> JaggedIndex<T> for RowIndex {
44 type Output = Vec<T>;
45
46 fn get(self, array: &Jagged<T>) -> Option<&Self::Output> {
47 array.data.get(self.0)
48 }
49
50 fn get_mut(self, array: &mut Jagged<T>) -> Option<&mut Self::Output> {
51 array.data.get_mut(self.0)
52 }
53}
54
55impl<T> JaggedRemove<T> for RowIndex {
56 type Output = Vec<T>;
57
58 fn remove(self, array: &mut Jagged<T>) -> Self::Output {
59 array.data.remove(self.0)
60 }
61}
62
63pub trait JaggedSlice<T> {
65 type Index: JaggedIndex<T>;
66 fn push_into(self, array: &mut Jagged<T>);
67 fn insert_into(self, index: Self::Index, array: &mut Jagged<T>);
68}
69
70#[derive(Default, Debug, PartialEq, Eq)]
72pub struct RowSlice<T> {
73 data: Vec<T>,
74}
75
76impl<T> From<Vec<T>> for RowSlice<T> {
77 fn from(val: Vec<T>) -> Self {
78 Self::new(val)
79 }
80}
81
82impl<T> RowSlice<T> {
83 #[must_use]
85 pub fn new(data: Vec<T>) -> Self {
86 Self { data }
87 }
88}
89
90impl<T> JaggedSlice<T> for T {
91 type Index = Index2;
92
93 fn push_into(self, array: &mut Jagged<T>) {
94 if let Some(row) = array.get_mut(RowIndex::new(array.len().saturating_sub(1))) {
95 row.push(self);
96 }
97 }
98
99 fn insert_into(self, index: Self::Index, array: &mut Jagged<T>) {
100 if let Some(line) = array.get_mut(RowIndex::new(index.row)) {
101 line.insert(index.col, self);
102 }
103 }
104}
105
106impl<T> JaggedSlice<T> for RowSlice<T>
107{
110 type Index = RowIndex;
111
112 fn push_into(self, array: &mut Jagged<T>) {
113 array.data.push(self.data);
114 }
115
116 fn insert_into(self, index: Self::Index, array: &mut Jagged<T>) {
117 array.data.insert(index.0, self.data);
118 }
119}
120
121impl<T> JaggedSlice<T> for Vec<T> {
122 type Index = RowIndex;
123
124 fn push_into(self, array: &mut Jagged<T>) {
125 array.data.push(self);
126 }
127
128 fn insert_into(self, index: Self::Index, array: &mut Jagged<T>) {
129 array.data.insert(index.0, self);
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 fn test_data() -> Jagged<char> {
137 Jagged::<char>::from(
138 "Hello\n\
139 World",
140 )
141 }
142
143 #[test]
144 fn test_get_index() {
145 let data = test_data();
146 let index = Index2::new(0, 4);
147
148 assert_eq!(index.get(&data), Some(&'o'));
149 }
150
151 #[test]
152 fn test_get_row() {
153 let data = test_data();
154 let index = RowIndex::new(1);
155
156 assert_eq!(index.get(&data), Some(&vec!['W', 'o', 'r', 'l', 'd']));
157 }
158}