@@ -35,10 +35,10 @@ pub struct Metadata {
3535 /// Document Version `UUIDv7`.
3636 ver : DocumentVersion ,
3737 /// Document Payload Content Type.
38- #[ serde( default , rename = "content-type" ) ]
38+ #[ serde( rename = "content-type" ) ]
3939 content_type : ContentType ,
4040 /// Document Payload Content Encoding.
41- #[ serde( default , rename = "content-encoding" ) ]
41+ #[ serde( rename = "content-encoding" ) ]
4242 content_encoding : Option < ContentEncoding > ,
4343 /// Additional Metadata Fields.
4444 #[ serde( flatten) ]
@@ -90,131 +90,113 @@ impl Display for Metadata {
9090 }
9191}
9292
93- impl Default for Metadata {
94- fn default ( ) -> Self {
95- Self {
96- doc_type : DocumentType :: invalid ( ) ,
97- id : DocumentId :: invalid ( ) ,
98- ver : DocumentVersion :: invalid ( ) ,
99- content_type : ContentType :: default ( ) ,
100- content_encoding : None ,
101- extra : AdditionalFields :: default ( ) ,
102- }
103- }
104- }
105-
10693impl TryFrom < & coset:: ProtectedHeader > for Metadata {
10794 type Error = crate :: error:: Error ;
10895
109- #[ allow( clippy:: too_many_lines) ]
11096 fn try_from ( protected : & coset:: ProtectedHeader ) -> Result < Self , Self :: Error > {
111- let mut metadata = Metadata :: default ( ) ;
11297 let mut errors = Vec :: new ( ) ;
11398
114- match protected. header . content_type . as_ref ( ) {
115- Some ( iana_content_type) => {
116- match ContentType :: try_from ( iana_content_type) {
117- Ok ( content_type) => metadata. content_type = content_type,
118- Err ( e) => {
119- errors. push ( anyhow ! ( "Invalid Document Content-Type: {e}" ) ) ;
120- } ,
121- }
122- } ,
123- None => {
124- errors. push ( anyhow ! (
125- "COSE document protected header `content-type` field is missing"
126- ) ) ;
127- } ,
99+ let mut content_type = None ;
100+ if let Some ( value) = protected. header . content_type . as_ref ( ) {
101+ match ContentType :: try_from ( value) {
102+ Ok ( ct) => content_type = Some ( ct) ,
103+ Err ( e) => errors. push ( anyhow ! ( "Invalid Document Content-Type: {e}" ) ) ,
104+ }
105+ } else {
106+ errors. push ( anyhow ! (
107+ "Invalid COSE protected header, missing Content-Type field"
108+ ) ) ;
128109 }
129110
111+ let mut content_encoding = None ;
130112 if let Some ( value) = cose_protected_header_find (
131113 protected,
132114 |key| matches ! ( key, coset:: Label :: Text ( label) if label. eq_ignore_ascii_case( CONTENT_ENCODING_KEY ) ) ,
133115 ) {
134116 match ContentEncoding :: try_from ( value) {
135- Ok ( encoding) => {
136- metadata. content_encoding = Some ( encoding) ;
137- } ,
138- Err ( e) => {
139- errors. push ( anyhow ! ( "Invalid Document Content Encoding: {e}" ) ) ;
140- } ,
117+ Ok ( ce) => content_encoding = Some ( ce) ,
118+ Err ( e) => errors. push ( anyhow ! ( "Invalid Document Content Encoding: {e}" ) ) ,
141119 }
142120 } else {
143121 errors. push ( anyhow ! (
144- "Invalid COSE document protected header '{CONTENT_ENCODING_KEY}' is missing "
122+ "Invalid COSE protected header, missing Content-Encoding field "
145123 ) ) ;
146124 }
147125
148- if let Some ( doc_type) = cose_protected_header_find ( protected, |key| {
126+ let mut doc_type = None ;
127+ if let Some ( value) = cose_protected_header_find ( protected, |key| {
149128 key == & coset:: Label :: Text ( "type" . to_string ( ) )
150129 } ) {
151- match UuidV4 :: try_from ( doc_type) {
152- Ok ( doc_type_uuid) => {
153- metadata. doc_type = doc_type_uuid. into ( ) ;
154- } ,
155- Err ( e) => {
156- errors. push ( anyhow ! ( "Document `type` is invalid: {e}" ) ) ;
157- } ,
130+ match UuidV4 :: try_from ( value) {
131+ Ok ( uuid) => doc_type = Some ( uuid) ,
132+ Err ( e) => errors. push ( anyhow ! ( "Document `type` is invalid: {e}" ) ) ,
158133 }
159134 } else {
160135 errors. push ( anyhow ! (
161136 "Invalid COSE protected header, missing `type` field"
162137 ) ) ;
163138 }
164139
165- match cose_protected_header_find ( protected, |key| {
140+ let mut id = None ;
141+ if let Some ( value) = cose_protected_header_find ( protected, |key| {
166142 key == & coset:: Label :: Text ( "id" . to_string ( ) )
167143 } ) {
168- Some ( doc_id) => {
169- match UuidV7 :: try_from ( doc_id) {
170- Ok ( doc_id_uuid) => {
171- metadata. id = doc_id_uuid. into ( ) ;
172- } ,
173- Err ( e) => {
174- errors. push ( anyhow ! ( "Document `id` is invalid: {e}" ) ) ;
175- } ,
176- }
177- } ,
178- None => errors. push ( anyhow ! ( "Invalid COSE protected header, missing `id` field" ) ) ,
179- } ;
144+ match UuidV7 :: try_from ( value) {
145+ Ok ( uuid) => id = Some ( uuid) ,
146+ Err ( e) => errors. push ( anyhow ! ( "Document `id` is invalid: {e}" ) ) ,
147+ }
148+ } else {
149+ errors. push ( anyhow ! ( "Invalid COSE protected header, missing `id` field" ) ) ;
150+ }
180151
181- match cose_protected_header_find ( protected, |key| {
152+ let mut ver = None ;
153+ if let Some ( value) = cose_protected_header_find ( protected, |key| {
182154 key == & coset:: Label :: Text ( "ver" . to_string ( ) )
183155 } ) {
184- Some ( doc_ver) => {
185- match UuidV7 :: try_from ( doc_ver) {
186- Ok ( doc_ver_uuid) => {
187- if doc_ver_uuid. uuid ( ) < metadata. id . uuid ( ) {
188- errors. push ( anyhow ! (
189- "Document Version {doc_ver_uuid} cannot be smaller than Document ID {}" , metadata. id
190- ) ) ;
191- } else {
192- metadata. ver = doc_ver_uuid. into ( ) ;
193- }
194- } ,
195- Err ( e) => {
196- errors. push ( anyhow ! (
197- "Invalid COSE protected header `ver` field, err: {e}"
198- ) ) ;
199- } ,
200- }
201- } ,
202- None => {
203- errors. push ( anyhow ! (
204- "Invalid COSE protected header, missing `ver` field"
205- ) ) ;
206- } ,
156+ match UuidV7 :: try_from ( value) {
157+ Ok ( uuid) => ver = Some ( uuid) ,
158+ Err ( e) => errors. push ( anyhow ! ( "Document `ver` is invalid: {e}" ) ) ,
159+ }
160+ } else {
161+ errors. push ( anyhow ! (
162+ "Invalid COSE protected header, missing `ver` field"
163+ ) ) ;
207164 }
208165
209- match AdditionalFields :: try_from ( protected) {
210- Ok ( extra) => metadata. extra = extra,
211- Err ( e) => errors. extend ( e) ,
212- } ;
166+ let extra = AdditionalFields :: try_from ( protected) . map_or_else (
167+ |e| {
168+ errors. extend ( e) ;
169+ None
170+ } ,
171+ Some ,
172+ ) ;
173+
174+ match ( content_type, content_encoding, id, doc_type, ver, extra) {
175+ (
176+ Some ( content_type) ,
177+ content_encoding,
178+ Some ( id) ,
179+ Some ( doc_type) ,
180+ Some ( ver) ,
181+ Some ( extra) ,
182+ ) => {
183+ if ver < id {
184+ errors. push ( anyhow ! (
185+ "Document Version {ver} cannot be smaller than Document ID {id}" ,
186+ ) ) ;
187+ return Err ( crate :: error:: Error ( errors) ) ;
188+ }
213189
214- if errors. is_empty ( ) {
215- Ok ( metadata)
216- } else {
217- Err ( errors. into ( ) )
190+ Ok ( Self {
191+ doc_type : doc_type. into ( ) ,
192+ id : id. into ( ) ,
193+ ver : ver. into ( ) ,
194+ content_encoding,
195+ content_type,
196+ extra,
197+ } )
198+ } ,
199+ _ => Err ( crate :: error:: Error ( errors) ) ,
218200 }
219201 }
220202}
0 commit comments