Add inet support
It's lossy ATM, since IpAddr doesn't store the netmask. Closes #88
This commit is contained in:
parent
db198a5b77
commit
3ac26d4961
@ -204,6 +204,10 @@ types. The driver currently supports the following conversions:
|
||||
<td>serialize::json::Json</td>
|
||||
<td>JSON</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>IpAddr</td>
|
||||
<td>INET</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>time::Timespec</td>
|
||||
<td>TIMESTAMP, TIMESTAMP WITH TIME ZONE</td>
|
||||
|
@ -98,7 +98,7 @@ pub mod types;
|
||||
|
||||
const CANARY: u32 = 0xdeadbeef;
|
||||
|
||||
/// A typedef of the result returned by many methods.
|
||||
/// A type alias of the result returned by many methods.
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
/// Specifies the target server to connect to.
|
||||
|
@ -2,6 +2,7 @@
|
||||
use serialize::json;
|
||||
use std::collections::HashMap;
|
||||
use std::io::{ByRefReader, BufReader};
|
||||
use std::io::net::ip::IpAddr;
|
||||
|
||||
use self::Type::*;
|
||||
use Result;
|
||||
@ -325,6 +326,7 @@ const JSONOID: Oid = 114;
|
||||
const JSONARRAYOID: Oid = 199;
|
||||
const FLOAT4OID: Oid = 700;
|
||||
const FLOAT8OID: Oid = 701;
|
||||
const INETOID: Oid = 869;
|
||||
const BOOLARRAYOID: Oid = 1000;
|
||||
const BYTEAARRAYOID: Oid = 1001;
|
||||
const CHARARRAYOID: Oid = 1002;
|
||||
@ -433,6 +435,8 @@ make_postgres_type!(
|
||||
FLOAT4OID => Float4,
|
||||
#[doc="FLOAT8/DOUBLE PRECISION"]
|
||||
FLOAT8OID => Float8,
|
||||
#[doc="INET"]
|
||||
INETOID => Inet,
|
||||
#[doc="BOOL[]"]
|
||||
BOOLARRAYOID => BoolArray member Bool,
|
||||
#[doc="BYTEA[]"]
|
||||
@ -538,6 +542,29 @@ impl RawFromSql for json::Json {
|
||||
}
|
||||
}
|
||||
|
||||
impl RawFromSql for IpAddr {
|
||||
fn raw_from_sql<R: Reader>(raw: &mut R) -> Result<IpAddr> {
|
||||
let family = try!(raw.read_u8());
|
||||
let _bits = try!(raw.read_u8());
|
||||
let _is_cidr = try!(raw.read_u8());
|
||||
let nb = try!(raw.read_u8());
|
||||
let mut buf = &*try!(raw.read_exact(nb as uint));
|
||||
|
||||
match family {
|
||||
2 if nb == 4 => Ok(IpAddr::Ipv4Addr(buf[0], buf[1], buf[2], buf[3])),
|
||||
3 if nb == 16 => Ok(IpAddr::Ipv6Addr(try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()),
|
||||
try!(buf.read_be_u16()))),
|
||||
_ => Err(Error::BadData),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
from_raw_from_impl!(Bool, bool)
|
||||
from_raw_from_impl!(ByteA, Vec<u8>)
|
||||
from_raw_from_impl!(Varchar | Text | CharN | Name, String)
|
||||
@ -548,6 +575,7 @@ from_raw_from_impl!(Int8, i64)
|
||||
from_raw_from_impl!(Float4, f32)
|
||||
from_raw_from_impl!(Float8, f64)
|
||||
from_raw_from_impl!(Json, json::Json)
|
||||
from_raw_from_impl!(Inet, IpAddr)
|
||||
|
||||
from_raw_from_impl!(Int4Range, Range<i32>)
|
||||
from_raw_from_impl!(Int8Range, Range<i64>)
|
||||
@ -668,10 +696,44 @@ impl RawToSql for json::Json {
|
||||
}
|
||||
}
|
||||
|
||||
impl RawToSql for IpAddr {
|
||||
fn raw_to_sql<W: Writer>(&self, raw: &mut W) -> Result<()> {
|
||||
match *self {
|
||||
IpAddr::Ipv4Addr(a, b, c, d) => {
|
||||
let buf = [2, // family
|
||||
32, // bits
|
||||
0, // is_cidr
|
||||
4, // nb
|
||||
a, b, c, d // addr
|
||||
];
|
||||
try!(raw.write(&buf));
|
||||
}
|
||||
IpAddr::Ipv6Addr(a, b, c, d, e, f, g, h) => {
|
||||
let buf = [3, // family
|
||||
128, // bits
|
||||
0, // is_cidr
|
||||
16, // nb
|
||||
];
|
||||
try!(raw.write(&buf));
|
||||
try!(raw.write_be_u16(a));
|
||||
try!(raw.write_be_u16(b));
|
||||
try!(raw.write_be_u16(c));
|
||||
try!(raw.write_be_u16(d));
|
||||
try!(raw.write_be_u16(e));
|
||||
try!(raw.write_be_u16(f));
|
||||
try!(raw.write_be_u16(g));
|
||||
try!(raw.write_be_u16(h));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
to_raw_to_impl!(Bool, bool)
|
||||
to_raw_to_impl!(ByteA, Vec<u8>)
|
||||
to_raw_to_impl!(Varchar | Text | CharN | Name, String)
|
||||
to_raw_to_impl!(Json, json::Json)
|
||||
to_raw_to_impl!(Inet, IpAddr)
|
||||
to_raw_to_impl!(Char, i8)
|
||||
to_raw_to_impl!(Int2, i16)
|
||||
to_raw_to_impl!(Int4, i32)
|
||||
|
@ -4,6 +4,7 @@ use std::f32;
|
||||
use std::f64;
|
||||
use std::fmt;
|
||||
use std::num::Float;
|
||||
use std::io::net::ip::IpAddr;
|
||||
|
||||
use postgres::{Connection, SslMode};
|
||||
use postgres::types::{ToSql, FromSql};
|
||||
@ -164,6 +165,15 @@ fn test_json_params() {
|
||||
(None, "NULL")])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inet_params() {
|
||||
test_type("INET", &[(Some(from_str::<IpAddr>("127.0.0.1").unwrap()),
|
||||
"'127.0.0.1'"),
|
||||
(Some(from_str("2001:0db8:85a3:0000:0000:8a2e:0370:7334").unwrap()),
|
||||
"'2001:0db8:85a3:0000:0000:8a2e:0370:7334'"),
|
||||
(None, "NULL")])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_int4range_params() {
|
||||
test_range!("INT4RANGE", i32, 100i32, "100", 200i32, "200")
|
||||
|
Loading…
Reference in New Issue
Block a user