@@ -19,7 +19,7 @@ macro_rules! check_types {
1919macro_rules! raw_from_impl {
2020 ( $t: ty, $f: ident) => (
2121 impl RawFromSql for $t {
22- fn raw_from_sql<R : Reader >( raw: & mut R ) -> Result <$t> {
22+ fn raw_from_sql<R : Reader >( _ : & Type , raw: & mut R ) -> Result <$t> {
2323 Ok ( try!( raw. $f( ) ) )
2424 }
2525 }
@@ -51,7 +51,7 @@ macro_rules! from_map_impl {
5151 fn from_sql( ty: & Type , raw: Option <& [ u8 ] >) -> Result <Option <$t>> {
5252 check_types!( $( $expected) ,+; ty) ;
5353 match raw {
54- Some ( buf) => ( $blk) ( buf) . map( |ok| Some ( ok) ) ,
54+ Some ( buf) => ( $blk) ( ty , buf) . map( |ok| Some ( ok) ) ,
5555 None => Ok ( None )
5656 }
5757 }
@@ -63,18 +63,18 @@ macro_rules! from_map_impl {
6363
6464macro_rules! from_raw_from_impl {
6565 ( $( $expected: pat) ,+; $t: ty) => (
66- from_map_impl!( $( $expected) ,+; $t, |& mut : mut buf: & [ u8 ] | {
66+ from_map_impl!( $( $expected) ,+; $t, |& mut : ty , mut buf: & [ u8 ] | {
6767 use types:: RawFromSql ;
6868
69- RawFromSql :: raw_from_sql( & mut buf)
69+ RawFromSql :: raw_from_sql( ty , & mut buf)
7070 } ) ;
7171 )
7272}
7373
7474macro_rules! raw_to_impl {
7575 ( $t: ty, $f: ident) => (
7676 impl RawToSql for $t {
77- fn raw_to_sql<W : Writer >( & self , w: & mut W ) -> Result <( ) > {
77+ fn raw_to_sql<W : Writer >( & self , _ : & Type , w: & mut W ) -> Result <( ) > {
7878 Ok ( try!( w. $f( * self ) ) )
7979 }
8080 }
@@ -118,7 +118,7 @@ macro_rules! to_raw_to_impl {
118118 check_types!( $( $oid) ,+; ty) ;
119119
120120 let mut writer = vec![ ] ;
121- try!( self . raw_to_sql( & mut writer) ) ;
121+ try!( self . raw_to_sql( ty , & mut writer) ) ;
122122 Ok ( Some ( writer) )
123123 }
124124 }
@@ -351,24 +351,27 @@ pub trait FromSql {
351351
352352/// A utility trait used by `FromSql` implementations
353353pub trait RawFromSql {
354- /// Creates a new value of this type from a reader of Postgre data.
355- fn raw_from_sql < R : Reader > ( raw : & mut R ) -> Result < Self > ;
354+ /// Creates a new value of this type from a `Reader` of Postgres data.
355+ ///
356+ /// It is the caller's responsibility to ensure that Postgres data of this
357+ /// type can be turned in to this type.
358+ fn raw_from_sql < R : Reader > ( ty : & Type , raw : & mut R ) -> Result < Self > ;
356359}
357360
358361impl RawFromSql for bool {
359- fn raw_from_sql < R : Reader > ( raw : & mut R ) -> Result < bool > {
362+ fn raw_from_sql < R : Reader > ( _ : & Type , raw : & mut R ) -> Result < bool > {
360363 Ok ( ( try!( raw. read_u8 ( ) ) ) != 0 )
361364 }
362365}
363366
364367impl RawFromSql for Vec < u8 > {
365- fn raw_from_sql < R : Reader > ( raw : & mut R ) -> Result < Vec < u8 > > {
368+ fn raw_from_sql < R : Reader > ( _ : & Type , raw : & mut R ) -> Result < Vec < u8 > > {
366369 Ok ( try!( raw. read_to_end ( ) ) )
367370 }
368371}
369372
370373impl RawFromSql for String {
371- fn raw_from_sql < R : Reader > ( raw : & mut R ) -> Result < String > {
374+ fn raw_from_sql < R : Reader > ( _ : & Type , raw : & mut R ) -> Result < String > {
372375 String :: from_utf8 ( try!( raw. read_to_end ( ) ) ) . map_err ( |_| Error :: BadData )
373376 }
374377}
@@ -382,13 +385,19 @@ raw_from_impl!(f32, read_be_f32);
382385raw_from_impl ! ( f64 , read_be_f64) ;
383386
384387impl RawFromSql for json:: Json {
385- fn raw_from_sql < R : Reader > ( raw : & mut R ) -> Result < json:: Json > {
388+ fn raw_from_sql < R : Reader > ( ty : & Type , raw : & mut R ) -> Result < json:: Json > {
389+ if let Type :: Jsonb = * ty {
390+ // We only support version 1 of the jsonb binary format
391+ if try!( raw. read_u8 ( ) ) != 1 {
392+ return Err ( Error :: BadData ) ;
393+ }
394+ }
386395 json:: Json :: from_reader ( raw) . map_err ( |_| Error :: BadData )
387396 }
388397}
389398
390399impl RawFromSql for IpAddr {
391- fn raw_from_sql < R : Reader > ( raw : & mut R ) -> Result < IpAddr > {
400+ fn raw_from_sql < R : Reader > ( _ : & Type , raw : & mut R ) -> Result < IpAddr > {
392401 let family = try!( raw. read_u8 ( ) ) ;
393402 let _bits = try!( raw. read_u8 ( ) ) ;
394403 let _is_cidr = try!( raw. read_u8 ( ) ) ;
@@ -424,7 +433,7 @@ from_raw_from_impl!(Type::Oid; u32);
424433from_raw_from_impl ! ( Type :: Int8 ; i64 ) ;
425434from_raw_from_impl ! ( Type :: Float4 ; f32 ) ;
426435from_raw_from_impl ! ( Type :: Float8 ; f64 ) ;
427- from_raw_from_impl ! ( Type :: Json ; json:: Json ) ;
436+ from_raw_from_impl ! ( Type :: Json , Type :: Jsonb ; json:: Json ) ;
428437from_raw_from_impl ! ( Type :: Inet , Type :: Cidr ; IpAddr ) ;
429438
430439impl FromSql for Option < String > {
@@ -437,7 +446,7 @@ impl FromSql for Option<String> {
437446
438447 match raw {
439448 Some ( mut buf) => {
440- Ok ( Some ( try!( RawFromSql :: raw_from_sql ( & mut buf) ) ) )
449+ Ok ( Some ( try!( RawFromSql :: raw_from_sql ( ty , & mut buf) ) ) )
441450 }
442451 None => Ok ( None )
443452 }
@@ -500,25 +509,28 @@ pub trait ToSql {
500509
501510/// A utility trait used by `ToSql` implementations.
502511pub trait RawToSql {
503- /// Converts the value of `self` into the binary format appropriate for the
504- /// Postgres backend, writing it to `w`.
505- fn raw_to_sql < W : Writer > ( & self , w : & mut W ) -> Result < ( ) > ;
512+ /// Converts the value of `self` into the binary format of the specified
513+ /// Postgres type, writing it to `w`.
514+ ///
515+ /// It is the caller's responsibility to make sure that this type can be
516+ /// converted to the specified Postgres type.
517+ fn raw_to_sql < W : Writer > ( & self , ty : & Type , w : & mut W ) -> Result < ( ) > ;
506518}
507519
508520impl RawToSql for bool {
509- fn raw_to_sql < W : Writer > ( & self , w : & mut W ) -> Result < ( ) > {
521+ fn raw_to_sql < W : Writer > ( & self , _ : & Type , w : & mut W ) -> Result < ( ) > {
510522 Ok ( try!( w. write_u8 ( * self as u8 ) ) )
511523 }
512524}
513525
514526impl RawToSql for Vec < u8 > {
515- fn raw_to_sql < W : Writer > ( & self , w : & mut W ) -> Result < ( ) > {
527+ fn raw_to_sql < W : Writer > ( & self , _ : & Type , w : & mut W ) -> Result < ( ) > {
516528 Ok ( try!( w. write ( & * * self ) ) )
517529 }
518530}
519531
520532impl RawToSql for String {
521- fn raw_to_sql < W : Writer > ( & self , w : & mut W ) -> Result < ( ) > {
533+ fn raw_to_sql < W : Writer > ( & self , _ : & Type , w : & mut W ) -> Result < ( ) > {
522534 Ok ( try!( w. write ( self . as_bytes ( ) ) ) )
523535 }
524536}
@@ -532,13 +544,17 @@ raw_to_impl!(f32, write_be_f32);
532544raw_to_impl ! ( f64 , write_be_f64) ;
533545
534546impl RawToSql for json:: Json {
535- fn raw_to_sql < W : Writer > ( & self , raw : & mut W ) -> Result < ( ) > {
547+ fn raw_to_sql < W : Writer > ( & self , ty : & Type , raw : & mut W ) -> Result < ( ) > {
548+ if let Type :: Jsonb = * ty {
549+ try!( raw. write_u8 ( 1 ) ) ;
550+ }
551+
536552 Ok ( try!( write ! ( raw, "{}" , self ) ) )
537553 }
538554}
539555
540556impl RawToSql for IpAddr {
541- fn raw_to_sql < W : Writer > ( & self , raw : & mut W ) -> Result < ( ) > {
557+ fn raw_to_sql < W : Writer > ( & self , _ : & Type , raw : & mut W ) -> Result < ( ) > {
542558 match * self {
543559 IpAddr :: Ipv4Addr ( a, b, c, d) => {
544560 try!( raw. write ( & [ 2 , // family
@@ -570,7 +586,7 @@ impl RawToSql for IpAddr {
570586
571587to_raw_to_impl ! ( Type :: Bool ; bool ) ;
572588to_raw_to_impl ! ( Type :: ByteA ; Vec <u8 >) ;
573- to_raw_to_impl ! ( Type :: Json ; json:: Json ) ;
589+ to_raw_to_impl ! ( Type :: Json , Type :: Jsonb ; json:: Json ) ;
574590to_raw_to_impl ! ( Type :: Inet , Type :: Cidr ; IpAddr ) ;
575591to_raw_to_impl ! ( Type :: Char ; i8 ) ;
576592to_raw_to_impl ! ( Type :: Int2 ; i16 ) ;
0 commit comments