1
1
use crate :: { metadata:: MetadataValue , Status } ;
2
- use bytes:: { Buf , BytesMut } ;
2
+ use bytes:: { Buf , BufMut , BytesMut } ;
3
3
#[ cfg( feature = "gzip" ) ]
4
4
use flate2:: read:: { GzDecoder , GzEncoder } ;
5
5
use std:: fmt;
@@ -10,62 +10,64 @@ pub(crate) const ENCODING_HEADER: &str = "grpc-encoding";
10
10
pub ( crate ) const ACCEPT_ENCODING_HEADER : & str = "grpc-accept-encoding" ;
11
11
12
12
/// Struct used to configure which encodings are enabled on a server or channel.
13
+ ///
14
+ /// Represents an ordered list of compression encodings that are enabled.
13
15
#[ derive( Debug , Default , Clone , Copy ) ]
14
16
pub struct EnabledCompressionEncodings {
15
- #[ cfg( feature = "gzip" ) ]
16
- pub ( crate ) gzip : bool ,
17
- #[ cfg( feature = "zstd" ) ]
18
- pub ( crate ) zstd : bool ,
17
+ inner : [ Option < CompressionEncoding > ; 2 ] ,
19
18
}
20
19
21
20
impl EnabledCompressionEncodings {
22
- /// Check if a [`CompressionEncoding`] is enabled.
23
- pub fn is_enabled ( & self , encoding : CompressionEncoding ) -> bool {
24
- match encoding {
25
- #[ cfg( feature = "gzip" ) ]
26
- CompressionEncoding :: Gzip => self . gzip ,
27
- #[ cfg( feature = "zstd" ) ]
28
- CompressionEncoding :: Zstd => self . zstd ,
29
- }
30
- }
31
-
32
21
/// Enable a [`CompressionEncoding`].
22
+ ///
23
+ /// Adds the new encoding to the end of the encoding list.
33
24
pub fn enable ( & mut self , encoding : CompressionEncoding ) {
34
- match encoding {
35
- #[ cfg( feature = "gzip" ) ]
36
- CompressionEncoding :: Gzip => self . gzip = true ,
37
- #[ cfg( feature = "zstd" ) ]
38
- CompressionEncoding :: Zstd => self . zstd = true ,
25
+ for e in self . inner . iter_mut ( ) {
26
+ match e {
27
+ Some ( e) if * e == encoding => return ,
28
+ None => {
29
+ * e = Some ( encoding) ;
30
+ return ;
31
+ }
32
+ _ => continue ,
33
+ }
39
34
}
40
35
}
41
36
37
+ /// Remove the last [`CompressionEncoding`].
38
+ pub fn pop ( & mut self ) -> Option < CompressionEncoding > {
39
+ self . inner
40
+ . iter_mut ( )
41
+ . rev ( )
42
+ . find ( |entry| entry. is_some ( ) ) ?
43
+ . take ( )
44
+ }
45
+
42
46
pub ( crate ) fn into_accept_encoding_header_value ( self ) -> Option < http:: HeaderValue > {
43
- match ( self . is_gzip_enabled ( ) , self . is_zstd_enabled ( ) ) {
44
- ( true , false ) => Some ( http:: HeaderValue :: from_static ( "gzip,identity" ) ) ,
45
- ( false , true ) => Some ( http:: HeaderValue :: from_static ( "zstd,identity" ) ) ,
46
- ( true , true ) => Some ( http:: HeaderValue :: from_static ( "gzip,zstd,identity" ) ) ,
47
- ( false , false ) => None ,
47
+ let mut value = BytesMut :: new ( ) ;
48
+ for encoding in self . inner . into_iter ( ) . flatten ( ) {
49
+ if !value. is_empty ( ) {
50
+ value. put_slice ( b"," ) ;
51
+ }
52
+ value. put_slice ( encoding. as_str ( ) . as_bytes ( ) ) ;
48
53
}
49
- }
50
54
51
- #[ cfg( feature = "gzip" ) ]
52
- const fn is_gzip_enabled ( & self ) -> bool {
53
- self . gzip
54
- }
55
+ if value. is_empty ( ) {
56
+ return None ;
57
+ }
55
58
56
- #[ cfg( not( feature = "gzip" ) ) ]
57
- const fn is_gzip_enabled ( & self ) -> bool {
58
- false
59
+ value. put_slice ( b",identity" ) ;
60
+ Some ( http:: HeaderValue :: from_maybe_shared ( value) . unwrap ( ) )
59
61
}
60
62
61
- # [ cfg ( feature = "zstd" ) ]
62
- const fn is_zstd_enabled ( & self ) -> bool {
63
- self . zstd
63
+ /// Check if a [`CompressionEncoding`] is enabled.
64
+ pub fn is_enabled ( & self , encoding : CompressionEncoding ) -> bool {
65
+ self . inner . iter ( ) . any ( |e| * e == Some ( encoding ) )
64
66
}
65
67
66
- # [ cfg ( not ( feature = "zstd" ) ) ]
67
- const fn is_zstd_enabled ( & self ) -> bool {
68
- false
68
+ /// Check if any [`CompressionEncoding`]s are enabled.
69
+ pub fn is_empty ( & self ) -> bool {
70
+ self . inner . iter ( ) . all ( |e| e . is_none ( ) )
69
71
}
70
72
}
71
73
@@ -95,7 +97,7 @@ impl CompressionEncoding {
95
97
map : & http:: HeaderMap ,
96
98
enabled_encodings : EnabledCompressionEncodings ,
97
99
) -> Option < Self > {
98
- if ! enabled_encodings. is_gzip_enabled ( ) && !enabled_encodings . is_zstd_enabled ( ) {
100
+ if enabled_encodings. is_empty ( ) {
99
101
return None ;
100
102
}
101
103
@@ -157,9 +159,7 @@ impl CompressionEncoding {
157
159
}
158
160
}
159
161
160
- #[ allow( missing_docs) ]
161
- #[ cfg( any( feature = "gzip" , feature = "zstd" ) ) ]
162
- pub ( crate ) fn as_str ( & self ) -> & ' static str {
162
+ pub ( crate ) fn as_str ( self ) -> & ' static str {
163
163
match self {
164
164
#[ cfg( feature = "gzip" ) ]
165
165
CompressionEncoding :: Gzip => "gzip" ,
0 commit comments