Skip to content

Commit 764f266

Browse files
committed
Merge branch 'release-v0.5.1' into release
2 parents 8279824 + 7447f39 commit 764f266

File tree

5 files changed

+77
-11
lines changed

5 files changed

+77
-11
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
[package]
22
name = "postgres_array"
3-
version = "0.5.0"
3+
version = "0.5.1"
44
authors = ["Steven Fackler <sfackler@gmail.com>"]
55
license = "MIT"
66
description = "Array support for rust-postgres"
77
repository = "https://github.com/sfackler/rust-postgres-array"
8-
documentation = "https://sfackler.github.io/rust-postgres-array/doc/v0.5.0/postgres_array"
8+
documentation = "https://sfackler.github.io/rust-postgres-array/doc/v0.5.1/postgres_array"
99

1010
[dependencies]
11-
postgres = "0.9"
11+
postgres = ">= 0.9, < 0.11"
1212
byteorder = "0.3"
1313

1414
[dev-dependencies]

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
Support for PostgreSQL arrays in [rust-postgres](https://github.com/sfackler/rust-postgres).
55

6-
Documentation is available at https://sfackler.github.io/rust-postgres-array/doc/v0.5.0/postgres_array.
6+
Documentation is available at https://sfackler.github.io/rust-postgres-array/doc/v0.5.1/postgres_array.

src/array.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,50 @@
11
use std::ops::{Index, IndexMut};
22
use std::slice;
33
use std::vec;
4+
use std::fmt;
45

56
use Dimension;
67

78
/// A multi-dimensional array.
8-
#[derive(Debug, PartialEq, Eq, Clone)]
9+
#[derive(PartialEq, Eq, Clone)]
910
pub struct Array<T> {
1011
dims: Vec<Dimension>,
1112
data: Vec<T>,
1213
}
1314

15+
impl<T: fmt::Debug> fmt::Debug for Array<T> {
16+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
17+
if self.dims.iter().any(|dim| dim.lower_bound != 1) {
18+
for dim in &self.dims {
19+
try!(write!(fmt, "[{}:{}]", dim.lower_bound,
20+
dim.lower_bound + dim.len as isize - 1));
21+
}
22+
try!(write!(fmt, "="));
23+
}
24+
fmt_helper(0, &self.dims, &mut self.data.iter(), fmt)
25+
}
26+
}
27+
28+
fn fmt_helper<'a, T, I>(depth: usize,
29+
dims: &[Dimension],
30+
mut data: &mut I,
31+
fmt: &mut fmt::Formatter)
32+
-> fmt::Result
33+
where I: Iterator<Item=&'a T>, T: 'a+fmt::Debug {
34+
if depth == dims.len() {
35+
return write!(fmt, "{:?}", data.next().unwrap());
36+
}
37+
38+
try!(write!(fmt, "{{"));
39+
for i in 0..dims[depth].len {
40+
if i != 0 {
41+
try!(write!(fmt, ","));
42+
}
43+
try!(fmt_helper(depth + 1, dims, data, fmt));
44+
}
45+
write!(fmt, "}}")
46+
}
47+
1448
impl<T> Array<T> {
1549
/// Creates a new `Array` from its underlying components.
1650
///

src/impls.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::io::prelude::*;
22
use std::error;
33
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
44

5-
use postgres;
5+
use postgres::{self, Result};
66
use postgres::error::Error;
77
use postgres::types::{Type, Kind, ToSql, FromSql, Oid, IsNull, SessionInfo};
88

@@ -68,21 +68,29 @@ impl<T> ToSql for Array<T> where T: ToSql {
6868
_ => panic!("unexpected type {:?}", ty),
6969
};
7070

71-
try!(w.write_u32::<BigEndian>(self.dimensions().len() as u32));
71+
try!(w.write_i32::<BigEndian>(try!(downcast(self.dimensions().len()))));
7272
try!(w.write_i32::<BigEndian>(1));
7373
try!(w.write_u32::<BigEndian>(element_type.oid()));
7474

7575
for info in self.dimensions() {
76-
try!(w.write_u32::<BigEndian>(info.len as u32));
77-
try!(w.write_i32::<BigEndian>(info.lower_bound as i32));
76+
try!(w.write_i32::<BigEndian>(try!(downcast(info.len))));
77+
78+
let bound = if info.lower_bound > i32::max_value() as isize
79+
|| info.lower_bound < i32::min_value() as isize {
80+
let err: Box<error::Error+Sync+Send> = "value too large to transmit".into();
81+
return Err(Error::Conversion(err));
82+
} else {
83+
info.lower_bound as i32
84+
};
85+
try!(w.write_i32::<BigEndian>(bound));
7886
}
7987

8088
let mut inner_buf = vec![];
8189
for v in self {
8290
match try!(v.to_sql(element_type, &mut inner_buf, info)) {
8391
IsNull::Yes => try!(w.write_i32::<BigEndian>(-1)),
8492
IsNull::No => {
85-
try!(w.write_i32::<BigEndian>(inner_buf.len() as i32));
93+
try!(w.write_i32::<BigEndian>(try!(downcast(inner_buf.len()))));
8694
try!(w.write_all(&inner_buf));
8795
}
8896
}
@@ -102,6 +110,15 @@ impl<T> ToSql for Array<T> where T: ToSql {
102110
to_sql_checked!();
103111
}
104112

113+
fn downcast(len: usize) -> Result<i32> {
114+
if len > i32::max_value() as usize {
115+
let err: Box<error::Error+Sync+Send> = "value too large to transmit".into();
116+
Err(Error::Conversion(err))
117+
} else {
118+
Ok(len as i32)
119+
}
120+
}
121+
105122
#[cfg(test)]
106123
mod test {
107124
use std::fmt;

src/lib.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Multi-dimensional arrays with per-dimension specifiable lower bounds
2-
#![doc(html_root_url="https://sfackler.github.io/rust-postgres-array/doc/v0.5.0")]
2+
#![doc(html_root_url="https://sfackler.github.io/rust-postgres-array/doc/v0.5.1")]
33

44
#[macro_use(to_sql_checked)]
55
extern crate postgres;
@@ -118,4 +118,19 @@ mod tests {
118118
a[(0, 0)] = 3;
119119
assert_eq!(3, a[(0, 0)]);
120120
}
121+
122+
#[test]
123+
fn test_debug() {
124+
let a = Array::from_vec(vec![0i32, 1, 2, 3, 4], 1);
125+
assert_eq!("{0,1,2,3,4}", &format!("{:?}", a));
126+
127+
let a = Array::from_vec(vec![0i32, 1, 2, 3, 4], -3);
128+
assert_eq!("[-3:1]={0,1,2,3,4}", &format!("{:?}", a));
129+
130+
let mut a = Array::from_vec(vec![1i32, 2, 3], 3);
131+
a.wrap(-2);
132+
a.push(Array::from_vec(vec![4, 5, 6], 3));
133+
a.wrap(1);
134+
assert_eq!("[1:1][-2:-1][3:5]={{{1,2,3},{4,5,6}}}", &format!("{:?}", a));
135+
}
121136
}

0 commit comments

Comments
 (0)