1#![doc(html_root_url = "https://docs.rs/postgres_array/0.10")]
3
4#[doc(inline)]
5pub use crate::array::Array;
6
7pub mod array;
8mod impls;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct Dimension {
13 pub len: i32,
15 pub lower_bound: i32,
17}
18
19impl Dimension {
20 fn shift(&self, idx: i32) -> i32 {
21 let offset = self.lower_bound;
22 assert!(idx >= offset, "out of bounds array access");
23 assert!(
24 offset >= 0 || idx <= 0 || i32::max_value() - (-offset) >= idx,
25 "out of bounds array access"
26 );
27 match idx.checked_sub(offset) {
28 Some(shifted) => shifted,
29 None => panic!("out of bounds array access"),
30 }
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn test_from_vec() {
40 let a = Array::from_vec(vec![0i32, 1, 2], -1);
41 assert!(
42 &[Dimension {
43 len: 3,
44 lower_bound: -1,
45 },][..]
46 == a.dimensions()
47 );
48 assert_eq!(0, a[-1]);
49 assert_eq!(1, a[0]);
50 assert_eq!(2, a[1]);
51 }
52
53 #[test]
54 fn test_into_inner() {
55 let a = Array::from_vec(vec![0i32, 1, 2], -1);
56 let a = a.into_inner();
57 assert_eq!(a.len(), 3);
58 assert_eq!(0, a[0]);
59 assert_eq!(1, a[1]);
60 assert_eq!(2, a[2]);
61 }
62
63 #[test]
64 fn test_2d_slice_get() {
65 let mut a = Array::from_vec(vec![0i32, 1, 2], -1);
66 a.wrap(1);
67 assert_eq!(0, a[(1, -1)]);
68 assert_eq!(1, a[(1, 0)]);
69 assert_eq!(2, a[(1, 1)]);
70 }
71
72 #[test]
73 #[should_panic]
74 fn test_push_wrong_lower_bound() {
75 let mut a = Array::from_vec(vec![1i32], -1);
76 a.push(Array::from_vec(vec![2], 0));
77 }
78
79 #[test]
80 #[should_panic]
81 fn test_push_wrong_dims() {
82 let mut a = Array::from_vec(vec![1i32], -1);
83 a.wrap(1);
84 a.push(Array::from_vec(vec![1, 2], -1));
85 }
86
87 #[test]
88 #[should_panic]
89 fn test_push_wrong_dim_count() {
90 let mut a = Array::from_vec(vec![1i32], -1);
91 a.wrap(1);
92 let mut b = Array::from_vec(vec![2], -1);
93 b.wrap(1);
94 a.push(b);
95 }
96
97 #[test]
98 fn test_push_ok() {
99 let mut a = Array::from_vec(vec![1i32, 2], 0);
100 a.wrap(0);
101 a.push(Array::from_vec(vec![3, 4], 0));
102 assert_eq!(1, a[(0, 0)]);
103 assert_eq!(2, a[(0, 1)]);
104 assert_eq!(3, a[(1, 0)]);
105 assert_eq!(4, a[(1, 1)]);
106 }
107
108 #[test]
109 fn test_3d() {
110 let mut a = Array::from_vec(vec![0i32, 1], 0);
111 a.wrap(0);
112 a.push(Array::from_vec(vec![2, 3], 0));
113 a.wrap(0);
114 let mut b = Array::from_vec(vec![4, 5], 0);
115 b.wrap(0);
116 b.push(Array::from_vec(vec![6, 7], 0));
117 a.push(b);
118 assert_eq!(0, a[(0, 0, 0)]);
119 assert_eq!(1, a[(0, 0, 1)]);
120 assert_eq!(2, a[(0, 1, 0)]);
121 assert_eq!(3, a[(0, 1, 1)]);
122 assert_eq!(4, a[(1, 0, 0)]);
123 assert_eq!(5, a[(1, 0, 1)]);
124 assert_eq!(6, a[(1, 1, 0)]);
125 assert_eq!(7, a[(1, 1, 1)]);
126 }
127
128 #[test]
129 fn test_mut() {
130 let mut a = Array::from_vec(vec![1i32, 2], 0);
131 a.wrap(0);
132 a[(0, 0)] = 3;
133 assert_eq!(3, a[(0, 0)]);
134 }
135
136 #[test]
137 fn test_display() {
138 let a = Array::from_vec(vec![0i32, 1, 2, 3, 4], 1);
139 assert_eq!("{0,1,2,3,4}", &format!("{}", a));
140
141 let a = Array::from_vec(vec![0i32, 1, 2, 3, 4], -3);
142 assert_eq!("[-3:1]={0,1,2,3,4}", &format!("{}", a));
143
144 let mut a = Array::from_vec(vec![1i32, 2, 3], 3);
145 a.wrap(-2);
146 a.push(Array::from_vec(vec![4, 5, 6], 3));
147 a.wrap(1);
148 assert_eq!("[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}", &format!("{}", a));
149
150 let a: Array<String> = Array::from_parts(vec![], vec![]);
151 assert_eq!("{}", &format!("{}", a));
152 }
153}