1+ extern crate serde;
12extern crate serde_json;
23
4+ use self :: serde:: { Deserialize , Serialize } ;
35use self :: serde_json:: Value ;
46use std:: error:: Error ;
5- use std:: io:: { Read , Write } ;
7+ use std:: fmt:: Debug ;
8+ use std:: io:: Read ;
69
710use types:: { FromSql , IsNull , ToSql , Type } ;
811
9- impl < ' a > FromSql < ' a > for Value {
10- fn from_sql ( ty : & Type , mut raw : & [ u8 ] ) -> Result < Value , Box < Error + Sync + Send > > {
12+ #[ derive( Debug ) ]
13+ pub struct Json < T > ( pub T ) ;
14+
15+ impl < ' a , T > FromSql < ' a > for Json < T >
16+ where
17+ T : Deserialize < ' a > ,
18+ {
19+ fn from_sql ( ty : & Type , mut raw : & ' a [ u8 ] ) -> Result < Json < T > , Box < Error + Sync + Send > > {
1120 if * ty == Type :: JSONB {
1221 let mut b = [ 0 ; 1 ] ;
1322 raw. read_exact ( & mut b) ?;
@@ -16,21 +25,43 @@ impl<'a> FromSql<'a> for Value {
1625 return Err ( "unsupported JSONB encoding version" . into ( ) ) ;
1726 }
1827 }
19- serde_json:: de:: from_reader ( raw) . map_err ( Into :: into)
28+ serde_json:: de:: from_slice ( raw)
29+ . map ( Json )
30+ . map_err ( Into :: into)
2031 }
2132
2233 accepts ! ( JSON , JSONB ) ;
2334}
2435
25- impl ToSql for Value {
36+ impl < T > ToSql for Json < T >
37+ where
38+ T : Serialize + Debug ,
39+ {
2640 fn to_sql ( & self , ty : & Type , out : & mut Vec < u8 > ) -> Result < IsNull , Box < Error + Sync + Send > > {
2741 if * ty == Type :: JSONB {
2842 out. push ( 1 ) ;
2943 }
30- write ! ( out, "{}" , self ) ?;
44+ serde_json :: ser :: to_writer ( out, & self . 0 ) ?;
3145 Ok ( IsNull :: No )
3246 }
3347
3448 accepts ! ( JSON , JSONB ) ;
3549 to_sql_checked ! ( ) ;
3650}
51+
52+ impl < ' a > FromSql < ' a > for Value {
53+ fn from_sql ( ty : & Type , raw : & [ u8 ] ) -> Result < Value , Box < Error + Sync + Send > > {
54+ Json :: < Value > :: from_sql ( ty, raw) . map ( |json| json. 0 )
55+ }
56+
57+ accepts ! ( JSON , JSONB ) ;
58+ }
59+
60+ impl ToSql for Value {
61+ fn to_sql ( & self , ty : & Type , out : & mut Vec < u8 > ) -> Result < IsNull , Box < Error + Sync + Send > > {
62+ Json ( self ) . to_sql ( ty, out)
63+ }
64+
65+ accepts ! ( JSON , JSONB ) ;
66+ to_sql_checked ! ( ) ;
67+ }
0 commit comments