postgres_array/
lib.rs

1//! Multi-dimensional arrays with per-dimension specifiable lower bounds
2#![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/// Information about a dimension of an array.
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct Dimension {
13    /// The length of the dimension.
14    pub len: i32,
15    /// The index of the first element of the dimension.
16    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}