1
- use crate :: cbor:: { self , DateTimeParseError , TAG_RRR_RECORD } ;
1
+ use crate :: cbor:: { self , TAG_RRR_RECORD } ;
2
2
use crate :: crypto:: encryption:: EncryptionAlgorithm ;
3
3
use crate :: crypto:: signature:: SigningKey ;
4
4
use crate :: error:: { Error , IoResultExt , Result } ;
@@ -8,6 +8,7 @@ use crate::utils::serde::{BytesOrAscii, BytesOrHexString, Secret};
8
8
use async_fd_lock:: LockWrite ;
9
9
use chrono:: { DateTime , FixedOffset , TimeZone } ;
10
10
use coset:: cbor:: tag;
11
+ use coset:: cbor:: value:: Integer ;
11
12
use derive_more:: { Deref , DerefMut } ;
12
13
use futures:: { pin_mut, Stream , StreamExt } ;
13
14
use itertools:: Itertools ;
@@ -21,6 +22,7 @@ use segment::{
21
22
RecordVersion , Segment , SegmentEncryption , SegmentMetadata ,
22
23
} ;
23
24
use serde:: { Deserialize , Serialize } ;
25
+ use std:: fmt:: Display ;
24
26
use std:: iter;
25
27
use std:: ops:: { Deref , DerefMut } ;
26
28
use std:: { borrow:: Cow , fmt:: Debug , io:: Cursor } ;
@@ -54,28 +56,78 @@ impl DerefMut for SuccessionNonce {
54
56
}
55
57
}
56
58
59
+ #[ repr( u64 ) ]
60
+ pub enum RecordMetadataId {
61
+ CreatedAt = 1 ,
62
+ }
63
+
64
+ impl Display for RecordMetadataId {
65
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
66
+ match self {
67
+ Self :: CreatedAt => write ! ( f, "Created At" ) ,
68
+ }
69
+ }
70
+ }
71
+
72
+ impl TryFrom < & Integer > for RecordMetadataId {
73
+ type Error = ( ) ;
74
+
75
+ fn try_from ( value : & Integer ) -> std:: result:: Result < Self , ( ) > {
76
+ // Consider using the `num_enum` crate if this becomes cumbersome.
77
+ let value: u64 = value. clone ( ) . try_into ( ) . map_err ( |_| ( ) ) ?;
78
+ Ok ( match value {
79
+ _ if value == Self :: CreatedAt as u64 => Self :: CreatedAt ,
80
+ _ => return Err ( ( ) ) ,
81
+ } )
82
+ }
83
+ }
84
+
85
+ impl TryFrom < & cbor:: Value > for RecordMetadataId {
86
+ type Error = ( ) ;
87
+
88
+ fn try_from ( value : & cbor:: Value ) -> std:: result:: Result < Self , ( ) > {
89
+ let integer = value. as_integer ( ) . ok_or ( ( ) ) ?;
90
+
91
+ Self :: try_from ( & integer)
92
+ }
93
+ }
94
+
95
+ pub enum RecordMetadataKey < ' a > {
96
+ Id ( RecordMetadataId ) ,
97
+ Custom ( cbor:: HashableCborValueRef < ' a > ) ,
98
+ }
99
+
57
100
/// A CBOR map of metadata.
58
101
#[ derive( Clone , Debug , Default , Deref , DerefMut , PartialEq , Serialize , Deserialize ) ]
59
102
pub struct RecordMetadata ( pub cbor:: Map ) ;
60
103
61
104
impl RecordMetadata {
62
- pub const KEY_CREATED_AT : u64 = 1 ;
63
-
64
- pub fn get_created_at (
65
- & self ,
66
- ) -> std:: result:: Result < Option < DateTime < FixedOffset > > , DateTimeParseError > {
67
- self . get_date_time ( Self :: KEY_CREATED_AT )
105
+ pub fn get_created_at ( & self ) -> Option < DateTime < FixedOffset > > {
106
+ self . get_date_time ( RecordMetadataId :: CreatedAt as u64 )
68
107
}
69
108
70
109
pub fn insert_created_at < Tz : TimeZone > (
71
110
& mut self ,
72
111
date_time : DateTime < Tz > ,
73
112
) -> Option < cbor:: Value > {
74
- self . insert_date_time ( Self :: KEY_CREATED_AT , date_time)
113
+ self . insert_date_time ( RecordMetadataId :: CreatedAt as u64 , date_time)
75
114
}
76
115
77
116
pub fn shift_remove_created_at ( & mut self ) -> Option < cbor:: Value > {
78
- self . shift_remove ( Self :: KEY_CREATED_AT )
117
+ self . shift_remove ( RecordMetadataId :: CreatedAt as u64 )
118
+ }
119
+
120
+ pub fn iter_with_semantic_keys < ' a > (
121
+ & ' a self ,
122
+ ) -> impl Iterator < Item = ( RecordMetadataKey < ' a > , & ' a cbor:: Value ) > {
123
+ self . iter ( )
124
+ . map ( |( key, value) | match RecordMetadataId :: try_from ( & key. 0 ) {
125
+ Ok ( id) => ( RecordMetadataKey :: Id ( id) , value) ,
126
+ Err ( ( ) ) => (
127
+ RecordMetadataKey :: Custom ( cbor:: HashableCborValueRef ( & key. 0 ) ) ,
128
+ value,
129
+ ) ,
130
+ } )
79
131
}
80
132
}
81
133
@@ -343,6 +395,7 @@ impl Record {
343
395
}
344
396
}
345
397
398
+ /// Returns the available record versions, sorted from least to most recent.
346
399
#[ instrument( level = Level :: TRACE , ret, err) ]
347
400
pub async fn list_versions < L > (
348
401
registry : & Registry < L > ,
0 commit comments