Skip to content

Commit d77577e

Browse files
committed
Support BIT/VARBIT to BitVec
Closes rust-postgres#148
1 parent fee6d35 commit d77577e

5 files changed

Lines changed: 74 additions & 0 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ time = { version = "0.1.14", optional = true }
3838
unix_socket = { version = "0.4.1", optional = true, features = ["socket_timeout"] }
3939
uuid = { version = "0.1", optional = true }
4040
security-framework = { version = "0.1.1", optional = true }
41+
bit-vec = { version = "0.4", optional = true }
4142

4243
[dev-dependencies]
4344
url = "0.2"

src/types/bit_vec.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
extern crate bit_vec;
2+
3+
use std::io::prelude::*;
4+
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
5+
use self::bit_vec::BitVec;
6+
7+
use Result;
8+
use types::{FromSql, ToSql, IsNull, Type, SessionInfo, downcast};
9+
10+
impl FromSql for BitVec {
11+
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<BitVec> {
12+
let len = try!(raw.read_i32::<BigEndian>()) as usize;
13+
let mut bytes = vec![];
14+
try!(raw.take(((len + 7) / 8) as u64).read_to_end(&mut bytes));
15+
16+
let mut bitvec = BitVec::from_bytes(&bytes);
17+
while bitvec.len() > len {
18+
bitvec.pop();
19+
}
20+
21+
Ok(bitvec)
22+
}
23+
24+
accepts!(Type::Bit, Type::Varbit);
25+
}
26+
27+
impl ToSql for BitVec {
28+
fn to_sql<W: Write + ?Sized>(&self,
29+
_: &Type,
30+
mut out: &mut W,
31+
_: &SessionInfo)
32+
-> Result<IsNull> {
33+
try!(out.write_i32::<BigEndian>(try!(downcast(self.len()))));
34+
try!(out.write_all(&self.to_bytes()));
35+
36+
Ok(IsNull::No)
37+
}
38+
39+
accepts!(Type::Bit, Type::Varbit);
40+
to_sql_checked!();
41+
}

src/types/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ macro_rules! to_sql_checked {
4242
}
4343
}
4444

45+
#[cfg(feature = "bit-vec")]
46+
mod bit_vec;
4547
#[cfg(feature = "uuid")]
4648
mod uuid;
4749
#[cfg(feature = "time")]
@@ -586,6 +588,7 @@ impl error::Error for WasNull {
586588
/// | chrono::NaiveDate | DATE |
587589
/// | chrono::NaiveTime | TIME |
588590
/// | uuid::Uuid | UUID |
591+
/// | bit_vec::BitVec | BIT, VARBIT |
589592
///
590593
/// # Nullability
591594
///
@@ -796,6 +799,7 @@ pub enum IsNull {
796799
/// | chrono::NaiveDate | DATE |
797800
/// | chrono::NaiveTime | TIME |
798801
/// | uuid::Uuid | UUID |
802+
/// | bit_vec::BitVec | BIT, VARBIT |
799803
///
800804
/// # Nullability
801805
///

tests/types/bit_vec.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
extern crate bit_vec;
2+
3+
use self::bit_vec::BitVec;
4+
use types::test_type;
5+
6+
#[test]
7+
fn test_bit_params() {
8+
let mut bv = BitVec::from_bytes(&[0b0110_1001, 0b0000_0111]);
9+
bv.pop();
10+
bv.pop();
11+
test_type("BIT(14)", &[(Some(bv),
12+
"B'01101001000001'"),
13+
(None, "NULL")])
14+
}
15+
16+
#[test]
17+
fn test_varbit_params() {
18+
let mut bv = BitVec::from_bytes(&[0b0110_1001, 0b0000_0111]);
19+
bv.pop();
20+
bv.pop();
21+
test_type("VARBIT", &[(Some(bv),
22+
"B'01101001000001'"),
23+
(Some(BitVec::from_bytes(&[])),
24+
"B''"),
25+
(None, "NULL")])
26+
}

tests/types/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use postgres::{Connection, SslMode};
77
use postgres::error::Error;
88
use postgres::types::{ToSql, FromSql, Slice};
99

10+
#[cfg(feature = "bit-vec")]
11+
mod bit_vec;
1012
#[cfg(feature = "uuid")]
1113
mod uuid;
1214
#[cfg(feature = "time")]

0 commit comments

Comments
 (0)