22
33use crate :: { metadata:: ContentEncoding , CatalystSignedDocument } ;
44
5- /// `content-encoding` field validation rule
5+ /// `content-encoding` field validation rule.
66#[ derive( Debug ) ]
7- pub ( crate ) struct ContentEncodingRule {
8- /// expected `content-encoding` field
9- pub ( crate ) exp : ContentEncoding ,
10- /// optional flag for the `content-encoding` field
11- pub ( crate ) optional : bool ,
7+ pub ( crate ) enum ContentEncodingRule {
8+ /// Content Encoding field is optionally present in the document.
9+ Specified {
10+ /// expected `content-encoding` field.
11+ exp : ContentEncoding ,
12+ /// optional flag for the `content-encoding` field.
13+ optional : bool ,
14+ } ,
15+ /// Content Encoding field must not be present in the document.
16+ #[ allow( dead_code) ]
17+ NotSpecified ,
1218}
1319
1420impl ContentEncodingRule {
@@ -18,33 +24,50 @@ impl ContentEncodingRule {
1824 & self ,
1925 doc : & CatalystSignedDocument ,
2026 ) -> anyhow:: Result < bool > {
21- if let Some ( content_encoding) = doc. doc_content_encoding ( ) {
22- if content_encoding != self . exp {
23- doc. report ( ) . invalid_value (
24- "content-encoding" ,
25- content_encoding. to_string ( ) . as_str ( ) ,
26- self . exp . to_string ( ) . as_str ( ) ,
27- "Invalid Document content-encoding value" ,
28- ) ;
29- return Ok ( false ) ;
30- }
31- if content_encoding. decode ( doc. encoded_content ( ) ) . is_err ( ) {
32- doc. report ( ) . invalid_value (
33- "payload" ,
34- & hex:: encode ( doc. encoded_content ( ) ) ,
35- & format ! (
36- "Document content (payload) must decodable by the set content encoding type: {content_encoding}"
37- ) ,
38- "Invalid Document content value" ,
39- ) ;
40- return Ok ( false ) ;
41- }
42- } else if !self . optional {
43- doc. report ( ) . missing_field (
44- "content-encoding" ,
45- "Document must have a content-encoding field" ,
46- ) ;
47- return Ok ( false ) ;
27+ let context = "Content Encoding Rule check" ;
28+ match self {
29+ Self :: NotSpecified => {
30+ if let Some ( content_encoding) = doc. doc_content_encoding ( ) {
31+ doc. report ( ) . unknown_field (
32+ "content-encoding" ,
33+ & content_encoding. to_string ( ) ,
34+ & format ! (
35+ "{context}, document does not expect to have a content-encoding field"
36+ ) ,
37+ ) ;
38+ return Ok ( false ) ;
39+ }
40+ } ,
41+ Self :: Specified { exp, optional } => {
42+ if let Some ( content_encoding) = doc. doc_content_encoding ( ) {
43+ if content_encoding != * exp {
44+ doc. report ( ) . invalid_value (
45+ "content-encoding" ,
46+ content_encoding. to_string ( ) . as_str ( ) ,
47+ exp. to_string ( ) . as_str ( ) ,
48+ "Invalid Document content-encoding value" ,
49+ ) ;
50+ return Ok ( false ) ;
51+ }
52+ if content_encoding. decode ( doc. encoded_content ( ) ) . is_err ( ) {
53+ doc. report ( ) . invalid_value (
54+ "payload" ,
55+ & hex:: encode ( doc. encoded_content ( ) ) ,
56+ & format ! (
57+ "Document content (payload) must decodable by the set content encoding type: {content_encoding}"
58+ ) ,
59+ "Invalid Document content value" ,
60+ ) ;
61+ return Ok ( false ) ;
62+ }
63+ } else if !optional {
64+ doc. report ( ) . missing_field (
65+ "content-encoding" ,
66+ "Document must have a content-encoding field" ,
67+ ) ;
68+ return Ok ( false ) ;
69+ }
70+ } ,
4871 }
4972 Ok ( true )
5073 }
@@ -56,10 +79,10 @@ mod tests {
5679 use crate :: { builder:: tests:: Builder , metadata:: SupportedField } ;
5780
5881 #[ tokio:: test]
59- async fn content_encoding_rule_test ( ) {
82+ async fn content_encoding_is_specified_rule_test ( ) {
6083 let content_encoding = ContentEncoding :: Brotli ;
6184
62- let mut rule = ContentEncodingRule {
85+ let rule = ContentEncodingRule :: Specified {
6386 exp : content_encoding,
6487 optional : true ,
6588 } ;
@@ -79,7 +102,27 @@ mod tests {
79102 let doc = Builder :: new ( ) . build ( ) ;
80103 assert ! ( rule. check( & doc) . await . unwrap( ) ) ;
81104
82- rule. optional = false ;
105+ let rule = ContentEncodingRule :: Specified {
106+ exp : content_encoding,
107+ optional : false ,
108+ } ;
83109 assert ! ( !rule. check( & doc) . await . unwrap( ) ) ;
84110 }
111+
112+ #[ tokio:: test]
113+ async fn content_encoding_is_not_specified_rule_test ( ) {
114+ let content_encoding = ContentEncoding :: Brotli ;
115+
116+ let rule = ContentEncodingRule :: NotSpecified ;
117+
118+ // With Brotli content encoding
119+ let doc = Builder :: new ( )
120+ . with_metadata_field ( SupportedField :: ContentEncoding ( content_encoding) )
121+ . build ( ) ;
122+ assert ! ( !rule. check( & doc) . await . unwrap( ) ) ;
123+
124+ // No content encoding
125+ let doc = Builder :: new ( ) . build ( ) ;
126+ assert ! ( rule. check( & doc) . await . unwrap( ) ) ;
127+ }
85128}
0 commit comments