1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::io::prelude::*;
use byteorder::{WriteBytesExt, BigEndian};
use Result;
use error::Error;
use types::{Type, ToSql, Kind, IsNull, SessionInfo, downcast};
#[derive(Debug)]
pub struct Slice<'a, T: 'a + ToSql>(pub &'a [T]);
impl<'a, T: 'a + ToSql> ToSql for Slice<'a, T> {
fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) -> Result<IsNull> {
if !<Slice<'a, T> as ToSql>::accepts(ty) {
return Err(Error::WrongType(ty.clone()));
}
self.to_sql(ty, out, ctx)
}
fn to_sql<W: Write+?Sized>(&self, ty: &Type, mut w: &mut W, ctx: &SessionInfo) -> Result<IsNull> {
let member_type = match ty.kind() {
&Kind::Array(ref member) => member,
_ => panic!("expected array type"),
};
try!(w.write_i32::<BigEndian>(1));
try!(w.write_i32::<BigEndian>(1));
try!(w.write_u32::<BigEndian>(member_type.oid()));
try!(w.write_i32::<BigEndian>(try!(downcast(self.0.len()))));
try!(w.write_i32::<BigEndian>(0));
let mut inner_buf = vec![];
for e in self.0 {
match try!(e.to_sql(&member_type, &mut inner_buf, ctx)) {
IsNull::No => {
try!(w.write_i32::<BigEndian>(try!(downcast(inner_buf.len()))));
try!(w.write_all(&inner_buf));
}
IsNull::Yes => try!(w.write_i32::<BigEndian>(-1)),
}
inner_buf.clear();
}
Ok(IsNull::No)
}
fn accepts(ty: &Type) -> bool {
match ty.kind() {
&Kind::Array(ref member) => <T as ToSql>::accepts(member),
_ => false,
}
}
}