nano_web/
response_buffer.rs1use bytes::Bytes;
2use std::sync::Arc;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum Encoding {
6 Identity,
7 Gzip,
8 Brotli,
9 Zstd,
10}
11
12impl Encoding {
13 pub const ALL: [Self; 4] = [Self::Identity, Self::Gzip, Self::Brotli, Self::Zstd];
14
15 #[inline]
18 pub fn from_accept_encoding(accept: &str) -> Self {
19 let mut best = Self::Identity;
20 for part in accept.split(',') {
21 let token = part.split(';').next().unwrap_or("").trim();
22 match token {
23 "br" => return Self::Brotli, "zstd" => best = Self::Zstd,
25 "gzip" if !matches!(best, Self::Zstd) => best = Self::Gzip,
26 _ => {}
27 }
28 }
29 best
30 }
31}
32
33#[derive(Debug, Clone)]
34pub struct ResponseBuffer {
35 pub body: Bytes,
36 pub content_type: Arc<str>,
37 pub content_encoding: Option<&'static str>,
38 pub etag: Arc<str>,
39 pub last_modified: Arc<str>,
40 pub cache_control: Arc<str>,
41}
42
43impl ResponseBuffer {
44 pub fn new(
45 body: Bytes,
46 content_type: Arc<str>,
47 content_encoding: Option<&'static str>,
48 etag: Arc<str>,
49 last_modified: Arc<str>,
50 cache_control: Arc<str>,
51 ) -> Self {
52 Self {
53 body,
54 content_type,
55 content_encoding,
56 etag,
57 last_modified,
58 cache_control,
59 }
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn test_encoding_priority() {
69 assert_eq!(
70 Encoding::from_accept_encoding("gzip, br, zstd"),
71 Encoding::Brotli
72 );
73 assert_eq!(Encoding::from_accept_encoding("br"), Encoding::Brotli);
74 assert_eq!(Encoding::from_accept_encoding("gzip, zstd"), Encoding::Zstd);
75 assert_eq!(Encoding::from_accept_encoding("zstd"), Encoding::Zstd);
76 assert_eq!(Encoding::from_accept_encoding("gzip"), Encoding::Gzip);
77 assert_eq!(
78 Encoding::from_accept_encoding("deflate"),
79 Encoding::Identity
80 );
81 assert_eq!(Encoding::from_accept_encoding(""), Encoding::Identity);
82 }
83
84 #[test]
85 fn test_encoding_no_substring_false_positives() {
86 assert_eq!(
87 Encoding::from_accept_encoding("vibrant"),
88 Encoding::Identity
89 );
90 assert_eq!(Encoding::from_accept_encoding("broken"), Encoding::Identity);
91 }
92
93 #[test]
94 fn test_encoding_with_quality_values() {
95 assert_eq!(
96 Encoding::from_accept_encoding("gzip;q=1.0, br;q=0.8"),
97 Encoding::Brotli
98 );
99 assert_eq!(
100 Encoding::from_accept_encoding("gzip;q=0.5, zstd;q=1.0"),
101 Encoding::Zstd
102 );
103 }
104}