@@ -38,21 +38,39 @@ pub struct Metadata {
3838 /// Document Payload Content Encoding.
3939 #[ serde( default , rename = "content-encoding" ) ]
4040 content_encoding : Option < ContentEncoding > ,
41+ /// Additional Metadata Fields.
42+ #[ serde( flatten) ]
43+ extra : Fields ,
44+ /// Metadata Content Errors
45+ #[ serde( skip) ]
46+ content_errors : Vec < String > ,
47+ }
48+
49+ /// Optional Metadata Fields.
50+ ///
51+ /// These values are extracted from the COSE Sign protected header labels.
52+ #[ derive( Default , Debug , serde:: Deserialize ) ]
53+ struct Fields {
4154 /// Reference to the latest document.
4255 #[ serde( rename = "ref" ) ]
4356 doc_ref : Option < DocumentRef > ,
57+ /// Hash of the referenced document bytes.
58+ ref_hash : Option < Vec < u8 > > ,
4459 /// Reference to the document template.
4560 template : Option < DocumentRef > ,
4661 /// Reference to the document reply.
4762 reply : Option < DocumentRef > ,
4863 /// Reference to the document section.
4964 section : Option < String > ,
50- /// Metadata Content Errors
51- #[ serde( skip) ]
52- content_errors : Vec < String > ,
5365}
5466
5567impl Metadata {
68+ /// Are there any validation errors (as opposed to structural errors).
69+ #[ must_use]
70+ pub fn has_error ( & self ) -> bool {
71+ !self . content_errors . is_empty ( )
72+ }
73+
5674 /// Return Document Type `UUIDv4`.
5775 #[ must_use]
5876 pub fn doc_type ( & self ) -> uuid:: Uuid {
@@ -71,53 +89,53 @@ impl Metadata {
7189 self . ver . uuid ( )
7290 }
7391
92+ /// Returns the Document Content Type, if any.
93+ #[ must_use]
94+ pub fn content_type ( & self ) -> ContentType {
95+ self . content_type
96+ }
97+
98+ /// Returns the Document Content Encoding, if any.
99+ #[ must_use]
100+ pub fn content_encoding ( & self ) -> Option < ContentEncoding > {
101+ self . content_encoding
102+ }
103+
104+ /// Return Last Document Reference `Option<Vec<u8>>`.
105+ #[ must_use]
106+ pub fn doc_ref_hash ( & self ) -> Option < Vec < u8 > > {
107+ self . extra . ref_hash . clone ( )
108+ }
109+
74110 /// Return Last Document Reference `Option<DocumentRef>`.
75111 #[ must_use]
76112 pub fn doc_ref ( & self ) -> Option < DocumentRef > {
77- self . doc_ref
113+ self . extra . doc_ref
78114 }
79115
80116 /// Return Document Template `Option<DocumentRef>`.
81117 #[ must_use]
82118 pub fn doc_template ( & self ) -> Option < DocumentRef > {
83- self . template
119+ self . extra . template
84120 }
85121
86122 /// Return Document Reply `Option<DocumentRef>`.
87123 #[ must_use]
88124 pub fn doc_reply ( & self ) -> Option < DocumentRef > {
89- self . reply
125+ self . extra . reply
90126 }
91127
92128 /// Return Document Section `Option<String>`.
93129 #[ must_use]
94130 pub fn doc_section ( & self ) -> Option < String > {
95- self . section . clone ( )
96- }
97-
98- /// Are there any validation errors (as opposed to structural errors).
99- #[ must_use]
100- pub fn has_error ( & self ) -> bool {
101- !self . content_errors . is_empty ( )
131+ self . extra . section . clone ( )
102132 }
103133
104134 /// List of Content Errors.
105135 #[ must_use]
106136 pub fn content_errors ( & self ) -> & Vec < String > {
107137 & self . content_errors
108138 }
109-
110- /// Returns the Document Content Type, if any.
111- #[ must_use]
112- pub fn content_type ( & self ) -> ContentType {
113- self . content_type
114- }
115-
116- /// Returns the Document Content Encoding, if any.
117- #[ must_use]
118- pub fn content_encoding ( & self ) -> Option < ContentEncoding > {
119- self . content_encoding
120- }
121139}
122140
123141impl Display for Metadata {
@@ -126,12 +144,9 @@ impl Display for Metadata {
126144 writeln ! ( f, " type: {}," , self . doc_type) ?;
127145 writeln ! ( f, " id: {}," , self . id) ?;
128146 writeln ! ( f, " ver: {}," , self . ver) ?;
129- writeln ! ( f, " ref: {:?}," , self . doc_ref) ?;
130- writeln ! ( f, " template: {:?}," , self . template) ?;
131- writeln ! ( f, " reply: {:?}," , self . reply) ?;
132- writeln ! ( f, " section: {:?}" , self . section) ?;
133147 writeln ! ( f, " content_type: {}" , self . content_type) ?;
134148 writeln ! ( f, " content_encoding: {:?}" , self . content_encoding) ?;
149+ writeln ! ( f, " additional_fields: {:?}," , self . extra) ?;
135150 writeln ! ( f, "}}" )
136151 }
137152}
@@ -142,28 +157,14 @@ impl Default for Metadata {
142157 doc_type : DocumentType :: invalid ( ) ,
143158 id : DocumentId :: invalid ( ) ,
144159 ver : DocumentVersion :: invalid ( ) ,
145- doc_ref : None ,
146- template : None ,
147- reply : None ,
148- section : None ,
149160 content_type : ContentType :: default ( ) ,
150161 content_encoding : None ,
162+ extra : Fields :: default ( ) ,
151163 content_errors : Vec :: new ( ) ,
152164 }
153165 }
154166}
155167
156- /// Errors found when decoding content.
157- #[ derive( Default , Debug ) ]
158- struct ContentErrors ( Vec < String > ) ;
159-
160- impl ContentErrors {
161- /// Appends an element to the back of the collection
162- fn push ( & mut self , error_string : String ) {
163- self . 0 . push ( error_string) ;
164- }
165- }
166-
167168impl From < & coset:: ProtectedHeader > for Metadata {
168169 #[ allow( clippy:: too_many_lines) ]
169170 fn from ( protected : & coset:: ProtectedHeader ) -> Self {
@@ -261,7 +262,7 @@ impl From<&coset::ProtectedHeader> for Metadata {
261262 if let Some ( cbor_doc_ref) = cose_protected_header_find ( protected, "ref" ) {
262263 match DocumentRef :: try_from ( & cbor_doc_ref) {
263264 Ok ( doc_ref) => {
264- metadata. doc_ref = Some ( doc_ref) ;
265+ metadata. extra . doc_ref = Some ( doc_ref) ;
265266 } ,
266267 Err ( e) => {
267268 errors. push ( format ! (
@@ -274,7 +275,7 @@ impl From<&coset::ProtectedHeader> for Metadata {
274275 if let Some ( cbor_doc_template) = cose_protected_header_find ( protected, "template" ) {
275276 match DocumentRef :: try_from ( & cbor_doc_template) {
276277 Ok ( doc_template) => {
277- metadata. template = Some ( doc_template) ;
278+ metadata. extra . template = Some ( doc_template) ;
278279 } ,
279280 Err ( e) => {
280281 errors. push ( format ! (
@@ -287,7 +288,7 @@ impl From<&coset::ProtectedHeader> for Metadata {
287288 if let Some ( cbor_doc_reply) = cose_protected_header_find ( protected, "reply" ) {
288289 match DocumentRef :: try_from ( & cbor_doc_reply) {
289290 Ok ( doc_reply) => {
290- metadata. reply = Some ( doc_reply) ;
291+ metadata. extra . reply = Some ( doc_reply) ;
291292 } ,
292293 Err ( e) => {
293294 errors. push ( format ! (
@@ -300,7 +301,7 @@ impl From<&coset::ProtectedHeader> for Metadata {
300301 if let Some ( cbor_doc_section) = cose_protected_header_find ( protected, "section" ) {
301302 match cbor_doc_section. into_text ( ) {
302303 Ok ( doc_section) => {
303- metadata. section = Some ( doc_section) ;
304+ metadata. extra . section = Some ( doc_section) ;
304305 } ,
305306 Err ( e) => {
306307 errors. push ( format ! (
0 commit comments