1#[derive(Clone, Debug, Default)]
2pub struct Array2D<T> {
3 data: Vec<T>,
4 width: usize,
5 height: usize,
6}
7
8impl<T: Default + std::clone::Clone> Array2D<T> {
9 pub fn new(width: usize, height: usize) -> Self {
10 if width < 1 || height < 1 {
11 return Array2D {
12 data: vec![],
13 width: 0,
14 height: 0,
15 }
16 }
17 let size = (width * height) as usize;
18 Array2D {
19 data: vec![Default::default(); size],
20 width,
21 height,
22 }
23 }
24
25 pub fn populate_array_with_data(&mut self, data: Vec<T>) -> Result<(), &str> {
26 if data.len() > self.data.len() {
27 return Err("Data to populate array is larger than the array");
29 }
30 for (pos, e) in data.iter().enumerate() {
31 self.data[pos] = e.clone();
32 }
33 Ok(())
34 }
35
36 pub fn get_size(&self) -> usize {
37 self.data.len() as usize
38 }
39
40 pub fn get_height(&self) -> usize {
41 self.height
42 }
43
44 pub fn get_width(&self) -> usize {
45 self.width
46 }
47
48 pub fn get_value_at(&self, row: usize, column: usize) -> Result<T, &str>
49 where
50 T: Copy,
51 {
52 if row > self.height {
53 return Err("Invalid row for data access");
54 }
55 if column > self.width {
56 return Err("Invalid column for data access");
57 }
58 let index: usize = self.get_index(row, column);
59 Ok(self.data[index])
60 }
61
62 pub fn set_value_at(&mut self, row: usize, column: usize, data: T) {
63 let index: usize = self.get_index(row, column);
64 self.data[index] = data;
65 }
66
67 pub fn get_index(&self, row: usize, column: usize) -> usize {
68 self.width * row + column
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::Array2D;
75
76 #[test]
77 fn test_new_array() {
78 let _arr = Array2D::<u8>::new(4, 4);
79 assert!(true)
80 }
81
82 #[test]
83 fn test_array_size() {
84 let arr = Array2D::<u8>::new(4, 5);
85 assert_eq!(arr.get_size(), (4 * 5));
86 }
87
88 #[test]
89 fn test_array_populate_with_data() {
90 let mut arr = Array2D::<u8>::new(2, 2);
91 let data: [u8; 4] = [2; 4];
92 match arr.populate_array_with_data(data.to_vec()) {
93 Ok(_) => assert!(true),
94 Err(_) => assert!(false),
95 }
96 }
97
98 #[test]
99 fn test_array_populate_with_data_error() {
100 let mut array = Array2D::<u8>::new(2, 2);
101 let data: [u8; 5] = [2; 5];
102 match array.populate_array_with_data(data.to_vec()) {
103 Ok(_) => assert!(false),
104 Err(_) => assert!(true),
105 }
106 }
107
108 #[test]
109 fn test_get_height() {
110 let arr = Array2D::<u8>::new(80, 100);
111 assert_eq!(arr.get_height(), 100)
112 }
113
114 #[test]
115 fn test_get_width() {
116 let arr = Array2D::<u8>::new(80, 100);
117 assert_eq!(arr.get_width(), 80);
118 }
119
120 #[test]
121 fn test_get_value_at() {
122 let test_data = vec![1, 2, 3, 4];
123 let mut arr = Array2D::<i8>::new(2, 2);
124 match arr.populate_array_with_data(test_data) {
125 Ok(_) => assert!(true),
126 Err(_) => assert!(false),
127 }
128 let mut result: i8 = match arr.get_value_at(0, 0) {
129 Ok(r) => r,
130 Err(_) => -1,
131 };
132 assert_eq!(result, 1);
133 result = match arr.get_value_at(0, 1) {
134 Ok(r) => r,
135 Err(_) => -1,
136 };
137 assert_eq!(result, 2);
138 result = match arr.get_value_at(1, 0) {
139 Ok(r) => r,
140 Err(_) => -1,
141 };
142 assert_eq!(result, 3);
143 result = match arr.get_value_at(1, 1) {
144 Ok(r) => r,
145 Err(_) => -1,
146 };
147 assert_eq!(result, 4);
148 }
149
150 #[test]
151 fn test_set_value_at() {
152 let mut arr = Array2D::<i8>::new(4, 5);
153 arr.set_value_at(2, 3, 5);
154 let result = match arr.get_value_at(2, 3) {
155 Ok(r) => r,
156 Err(_) => -1,
157 };
158 assert_eq!(result, 5);
159 }
160}