Support BIT/VARBIT to BitVec

Closes #148
This commit is contained in:
Steven Fackler 2015-12-06 12:40:00 -08:00
parent fee6d358bf
commit d77577eaaa
5 changed files with 74 additions and 0 deletions

View File

@ -38,6 +38,7 @@ time = { version = "0.1.14", optional = true }
unix_socket = { version = "0.4.1", optional = true, features = ["socket_timeout"] }
uuid = { version = "0.1", optional = true }
security-framework = { version = "0.1.1", optional = true }
bit-vec = { version = "0.4", optional = true }
[dev-dependencies]
url = "0.2"

41
src/types/bit_vec.rs Normal file
View File

@ -0,0 +1,41 @@
extern crate bit_vec;
use std::io::prelude::*;
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian};
use self::bit_vec::BitVec;
use Result;
use types::{FromSql, ToSql, IsNull, Type, SessionInfo, downcast};
impl FromSql for BitVec {
fn from_sql<R: Read>(_: &Type, raw: &mut R, _: &SessionInfo) -> Result<BitVec> {
let len = try!(raw.read_i32::<BigEndian>()) as usize;
let mut bytes = vec![];
try!(raw.take(((len + 7) / 8) as u64).read_to_end(&mut bytes));
let mut bitvec = BitVec::from_bytes(&bytes);
while bitvec.len() > len {
bitvec.pop();
}
Ok(bitvec)
}
accepts!(Type::Bit, Type::Varbit);
}
impl ToSql for BitVec {
fn to_sql<W: Write + ?Sized>(&self,
_: &Type,
mut out: &mut W,
_: &SessionInfo)
-> Result<IsNull> {
try!(out.write_i32::<BigEndian>(try!(downcast(self.len()))));
try!(out.write_all(&self.to_bytes()));
Ok(IsNull::No)
}
accepts!(Type::Bit, Type::Varbit);
to_sql_checked!();
}

View File

@ -42,6 +42,8 @@ macro_rules! to_sql_checked {
}
}
#[cfg(feature = "bit-vec")]
mod bit_vec;
#[cfg(feature = "uuid")]
mod uuid;
#[cfg(feature = "time")]
@ -586,6 +588,7 @@ impl error::Error for WasNull {
/// | chrono::NaiveDate | DATE |
/// | chrono::NaiveTime | TIME |
/// | uuid::Uuid | UUID |
/// | bit_vec::BitVec | BIT, VARBIT |
///
/// # Nullability
///
@ -796,6 +799,7 @@ pub enum IsNull {
/// | chrono::NaiveDate | DATE |
/// | chrono::NaiveTime | TIME |
/// | uuid::Uuid | UUID |
/// | bit_vec::BitVec | BIT, VARBIT |
///
/// # Nullability
///

26
tests/types/bit_vec.rs Normal file
View File

@ -0,0 +1,26 @@
extern crate bit_vec;
use self::bit_vec::BitVec;
use types::test_type;
#[test]
fn test_bit_params() {
let mut bv = BitVec::from_bytes(&[0b0110_1001, 0b0000_0111]);
bv.pop();
bv.pop();
test_type("BIT(14)", &[(Some(bv),
"B'01101001000001'"),
(None, "NULL")])
}
#[test]
fn test_varbit_params() {
let mut bv = BitVec::from_bytes(&[0b0110_1001, 0b0000_0111]);
bv.pop();
bv.pop();
test_type("VARBIT", &[(Some(bv),
"B'01101001000001'"),
(Some(BitVec::from_bytes(&[])),
"B''"),
(None, "NULL")])
}

View File

@ -7,6 +7,8 @@ use postgres::{Connection, SslMode};
use postgres::error::Error;
use postgres::types::{ToSql, FromSql, Slice};
#[cfg(feature = "bit-vec")]
mod bit_vec;
#[cfg(feature = "uuid")]
mod uuid;
#[cfg(feature = "time")]