@@ -27,7 +27,7 @@ pub type Md5Bytes = [u8; 16];
2727/// let metadata = cache.read_metadata(&b"MY_KEY").unwrap();
2828/// # }
2929/// ```
30- #[ derive( Debug , serde :: Deserialize , serde :: Serialize ) ]
30+ #[ derive( Debug ) ]
3131pub struct Metadata {
3232 /// Size in bytes of the corresponding entry
3333 size : u64 ,
@@ -68,13 +68,75 @@ impl Metadata {
6868 }
6969
7070 /// Serializes the metadata into bytes
71- pub ( crate ) fn serialize ( & self ) -> Result < Vec < u8 > > {
72- bson:: serialize_to_vec ( self ) . map_err ( ForcepError :: MetaSer )
71+ pub ( crate ) fn serialize ( & self ) -> Vec < u8 > {
72+ use bson:: {
73+ cstr,
74+ raw:: { RawBinaryRef , RawBson , RawDocumentBuf } ,
75+ } ;
76+
77+ let mut doc = RawDocumentBuf :: new ( ) ;
78+ doc. append ( cstr ! ( "size" ) , RawBson :: Int64 ( self . size as i64 ) ) ;
79+ doc. append (
80+ cstr ! ( "last_modified" ) ,
81+ RawBson :: Int64 ( self . last_modified as i64 ) ,
82+ ) ;
83+ doc. append (
84+ cstr ! ( "last_accessed" ) ,
85+ RawBson :: Int64 ( self . last_accessed as i64 ) ,
86+ ) ;
87+ doc. append ( cstr ! ( "hits" ) , RawBson :: Int64 ( self . hits as i64 ) ) ;
88+ doc. append (
89+ cstr ! ( "integrity" ) ,
90+ RawBinaryRef {
91+ subtype : bson:: spec:: BinarySubtype :: Md5 ,
92+ bytes : & self . integrity ,
93+ } ,
94+ ) ;
95+ doc. into_bytes ( )
7396 }
7497
7598 /// Deserializes a slice of bytes into metadata
7699 pub ( crate ) fn deserialize ( buf : & [ u8 ] ) -> Result < Self > {
77- bson:: deserialize_from_slice ( buf) . map_err ( ForcepError :: MetaDe )
100+ use bson:: { error:: Error as BsonError , raw:: RawDocument , spec:: BinarySubtype } ;
101+
102+ let doc = RawDocument :: from_bytes ( buf) . map_err ( ForcepError :: MetaDe ) ?;
103+
104+ let make_error = |key : & str , msg : & str | -> ForcepError {
105+ let io_err = std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidData , msg. to_owned ( ) ) ;
106+ let mut err = BsonError :: from ( io_err) ;
107+ err. key = Some ( key. to_owned ( ) ) ;
108+ ForcepError :: MetaDe ( err)
109+ } ;
110+
111+ let read_u64 = |key : & str | -> Result < u64 > {
112+ doc. get_i64 ( key)
113+ . map ( |v| v as u64 )
114+ . map_err ( ForcepError :: MetaDe )
115+ } ;
116+
117+ let size = read_u64 ( "size" ) ?;
118+ let last_modified = read_u64 ( "last_modified" ) ?;
119+ let last_accessed = read_u64 ( "last_accessed" ) ?;
120+ let hits = read_u64 ( "hits" ) ?;
121+
122+ let binary = doc. get_binary ( "integrity" ) . map_err ( ForcepError :: MetaDe ) ?;
123+ if binary. subtype != BinarySubtype :: Md5 {
124+ return Err ( make_error ( "integrity" , "expected MD5 binary subtype" ) ) ;
125+ }
126+ const MD5_LEN : usize = 16 ;
127+ if binary. bytes . len ( ) != MD5_LEN {
128+ return Err ( make_error ( "integrity" , "integrity must contain 16 bytes" ) ) ;
129+ }
130+ let mut integrity = [ 0u8 ; MD5_LEN ] ;
131+ integrity. copy_from_slice ( binary. bytes ) ;
132+
133+ Ok ( Self {
134+ size,
135+ last_modified,
136+ last_accessed,
137+ hits,
138+ integrity,
139+ } )
78140 }
79141
80142 /// The size in bytes of the corresponding cache entry.
@@ -174,7 +236,7 @@ impl MetaDb {
174236 /// If a previous entry exists, it is simply overwritten.
175237 pub fn insert_metadata_for ( & self , key : & [ u8 ] , data : & [ u8 ] ) -> Result < Metadata > {
176238 let meta = Metadata :: new ( data) ;
177- let bytes = Metadata :: serialize ( & meta) ? ;
239+ let bytes = Metadata :: serialize ( & meta) ;
178240 self . db
179241 . insert ( key, & bytes[ ..] )
180242 . map_err ( ForcepError :: MetaDb ) ?;
@@ -200,7 +262,7 @@ impl MetaDb {
200262 meta. last_accessed = now_since_epoch ( ) ;
201263 meta. hits += 1 ;
202264 self . db
203- . insert ( key, Metadata :: serialize ( & meta) ? )
265+ . insert ( key, Metadata :: serialize ( & meta) )
204266 . map_err ( ForcepError :: MetaDb ) ?;
205267 Ok ( meta)
206268 }
@@ -264,7 +326,7 @@ mod test {
264326 fn metadata_ser_de ( ) {
265327 let db = create_db ( ) . unwrap ( ) ;
266328 let meta = db. insert_metadata_for ( & DATA , & DATA ) . unwrap ( ) ;
267- let ser_bytes = meta. serialize ( ) . unwrap ( ) ;
329+ let ser_bytes = meta. serialize ( ) ;
268330 let de = Metadata :: deserialize ( & ser_bytes) . unwrap ( ) ;
269331 assert_eq ! ( meta. get_integrity( ) , de. get_integrity( ) ) ;
270332 }
0 commit comments