@@ -462,29 +462,47 @@ from_array_impl!(PgInt4RangeArray, Range<i32>)
462462from_array_impl ! ( PgTsRangeArray | PgTstzRangeArray , Range <Timespec >)
463463from_array_impl ! ( PgInt8RangeArray , Range <i64 >)
464464
465- from_map_impl ! ( PgUnknownType { name: ~"hstore", .. },
466- HashMap<~str, Option<~str>>, |buf| {
467- let mut rdr = BufReader::new(buf.as_slice());
468- let mut map = HashMap::new();
465+ impl FromSql for Option < HashMap < ~str , Option < ~str > > > {
466+ fn from_sql ( ty : & PostgresType , raw : & Option < ~[ u8 ] > )
467+ -> Option < HashMap < ~str , Option < ~str > > > {
468+ match * ty {
469+ PgUnknownType { name : ref name, .. } if "hstore" == * name => { }
470+ _ => fail ! ( "Invalid Postgres type {}" , * ty)
471+ }
472+
473+ raw. as_ref ( ) . map ( |buf| {
474+ let mut rdr = BufReader :: new ( buf. as_slice ( ) ) ;
475+ let mut map = HashMap :: new ( ) ;
469476
470- let count = or_fail!(rdr.read_be_i32());
477+ let count = or_fail ! ( rdr. read_be_i32( ) ) ;
471478
472- for _ in range(0, count) {
473- let key_len = or_fail!(rdr.read_be_i32());
474- let key = str::from_utf8_owned(or_fail!(rdr.read_bytes(key_len as uint))).unwrap();
479+ for _ in range ( 0 , count) {
480+ let key_len = or_fail ! ( rdr. read_be_i32( ) ) ;
481+ let key = str:: from_utf8_owned ( or_fail ! ( rdr. read_bytes( key_len as uint) ) ) . unwrap ( ) ;
482+
483+ let val_len = or_fail ! ( rdr. read_be_i32( ) ) ;
484+ let val = if val_len < 0 {
485+ None
486+ } else {
487+ Some ( str:: from_utf8_owned ( or_fail ! ( rdr. read_bytes( val_len as uint) ) ) . unwrap ( ) )
488+ } ;
475489
476- let val_len = or_fail!(rdr.read_be_i32());
477- let val = if val_len < 0 {
478- None
479- } else {
480- Some(str::from_utf8_owned(or_fail!(rdr.read_bytes(val_len as uint))).unwrap())
481- };
490+ map. insert ( key, val) ;
491+ }
482492
483- map.insert(key, val);
493+ map
494+ } )
484495 }
496+ }
485497
486- map
487- })
498+ impl FromSql for HashMap < ~str , Option < ~str > > {
499+ fn from_sql ( ty : & PostgresType , raw : & Option < ~[ u8 ] > )
500+ -> HashMap < ~str , Option < ~str > > {
501+ // FIXME when you can specify Self types properly
502+ let ret: Option < HashMap < ~str , Option < ~str > > > = FromSql :: from_sql ( ty, raw) ;
503+ ret. unwrap ( )
504+ }
505+ }
488506
489507/// A trait for types that can be converted into Postgres values
490508pub trait ToSql {
@@ -745,9 +763,13 @@ to_array_impl!(PgTsRangeArray | PgTstzRangeArray, Range<Timespec>)
745763to_array_impl ! ( PgInt8RangeArray , Range <i64 >)
746764to_array_impl ! ( PgJsonArray , Json )
747765
748- impl<'a> ToSql for HashMap<~str, Option<~str>> {
766+ impl ToSql for HashMap < ~str , Option < ~str > > {
749767 fn to_sql ( & self , ty : & PostgresType ) -> ( Format , Option < ~[ u8 ] > ) {
750- check_types!(PgUnknownType { name: ~" hstore", .. }, ty)
768+ match * ty {
769+ PgUnknownType { name : ref name, .. } if "hstore" == * name => { }
770+ _ => fail ! ( "Invalid Postgres type {}" , * ty)
771+ }
772+
751773 let mut buf = MemWriter :: new ( ) ;
752774
753775 or_fail ! ( buf. write_be_i32( self . len( ) as i32 ) ) ;
@@ -768,5 +790,17 @@ impl<'a> ToSql for HashMap<~str, Option<~str>> {
768790 ( Binary , Some ( buf. unwrap ( ) ) )
769791 }
770792}
771- to_option_impl!(PgUnknownType { name: ~" hstore" , .. } ,
772- HashMap <~str , Option <~str >>)
793+
794+ impl ToSql for Option < HashMap < ~str , Option < ~str > > > {
795+ fn to_sql ( & self , ty : & PostgresType ) -> ( Format , Option < ~[ u8 ] > ) {
796+ match * ty {
797+ PgUnknownType { name : ref name, .. } if "hstore" == * name => { }
798+ _ => fail ! ( "Invalid Postgres type {}" , * ty)
799+ }
800+
801+ match * self {
802+ Some ( ref inner) => inner. to_sql ( ty) ,
803+ None => ( Binary , None )
804+ }
805+ }
806+ }
0 commit comments