1#![forbid(unsafe_code)]
4
5pub mod error;
6
7#[macro_use]
8mod coder;
9mod coding;
10mod decode;
11
12#[cfg(any(feature = "br", feature = "gz", feature = "de", feature = "zs"))]
13mod writer;
14
15#[cfg(feature = "br")]
16mod brotli {
17 use std::io::{self, Write};
18
19 use brotli2::write::{BrotliDecoder, BrotliEncoder};
20 use bytes::Bytes;
21
22 use super::{coder::Code, writer::BytesMutWriter};
23
24 pub struct Decoder(Option<BrotliDecoder<BytesMutWriter>>);
25
26 impl Decoder {
27 pub(crate) fn new() -> Self {
28 Self(Some(BrotliDecoder::new(BytesMutWriter::new())))
29 }
30 }
31
32 pub struct Encoder(Option<BrotliEncoder<BytesMutWriter>>);
33
34 impl Encoder {
35 pub(crate) fn new(level: u32) -> Self {
36 Self(Some(BrotliEncoder::new(BytesMutWriter::new(), level)))
37 }
38 }
39
40 impl<T> Code<T> for Decoder
41 where
42 T: AsRef<[u8]>,
43 {
44 type Item = Bytes;
45
46 fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
47 let decoder = self.0.as_mut().unwrap();
48 decoder.write_all(item.as_ref())?;
49 decoder.flush()?;
50 let b = decoder.get_mut().take();
51 if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
52 }
53
54 fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
55 match self.0.take() {
56 Some(mut decoder) => {
57 let b = decoder.finish()?.take_owned();
58 Ok(Some(b))
59 }
60 None => Ok(None),
61 }
62 }
63
64 #[inline]
65 fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
66 self.0.is_none()
67 }
68 }
69
70 impl<T> Code<T> for Encoder
71 where
72 T: AsRef<[u8]>,
73 {
74 type Item = Bytes;
75
76 fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
77 let encoder = self.0.as_mut().unwrap();
78 encoder.write_all(item.as_ref())?;
79 encoder.flush()?;
80 let b = encoder.get_mut().take();
81 if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
82 }
83
84 fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
85 match self.0.take() {
86 Some(encoder) => {
87 let b = encoder.finish()?.take_owned();
88 Ok(Some(b))
89 }
90 None => Ok(None),
91 }
92 }
93
94 #[inline]
95 fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
96 self.0.is_none()
97 }
98 }
99}
100
101#[cfg(feature = "gz")]
102mod gzip {
103 use super::writer::BytesMutWriter;
104
105 use flate2::write::{GzDecoder, GzEncoder};
106
107 pub type Decoder = GzDecoder<BytesMutWriter>;
108 pub type Encoder = GzEncoder<BytesMutWriter>;
109
110 code_impl!(GzDecoder);
111 code_impl!(GzEncoder);
112}
113
114#[cfg(feature = "de")]
115mod deflate {
116 use super::writer::BytesMutWriter;
117
118 use flate2::write::{DeflateDecoder, DeflateEncoder};
119
120 pub type Decoder = DeflateDecoder<BytesMutWriter>;
121 pub type Encoder = DeflateEncoder<BytesMutWriter>;
122
123 code_impl!(DeflateDecoder);
124 code_impl!(DeflateEncoder);
125}
126
127#[cfg(feature = "zs")]
128mod zstandard {
129 use std::io::{self, Write};
130
131 use bytes::Bytes;
132 use zstd::stream::write::{Decoder as ZstdDecoder, Encoder as ZstdEncoder};
133
134 use super::{coder::Code, writer::BytesMutWriter};
135
136 pub struct Decoder(Option<ZstdDecoder<'static, BytesMutWriter>>);
137
138 impl Decoder {
139 pub(crate) fn new() -> Self {
140 Self(Some(ZstdDecoder::new(BytesMutWriter::new()).unwrap()))
141 }
142 }
143
144 pub struct Encoder(Option<ZstdEncoder<'static, BytesMutWriter>>);
145
146 impl Encoder {
147 pub(crate) fn new(level: i32) -> Self {
148 Self(Some(ZstdEncoder::new(BytesMutWriter::new(), level).unwrap()))
149 }
150 }
151
152 impl<T> Code<T> for Decoder
153 where
154 T: AsRef<[u8]>,
155 {
156 type Item = Bytes;
157
158 fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
159 let decoder = self.0.as_mut().unwrap();
160 decoder.write_all(item.as_ref())?;
161 decoder.flush()?;
162 let b = decoder.get_mut().take();
163 if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
164 }
165
166 fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
167 match self.0.take() {
168 Some(decoder) => {
169 let b = decoder.into_inner().take_owned();
170 Ok(Some(b))
171 }
172 None => Ok(None),
173 }
174 }
175
176 #[inline]
177 fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
178 self.0.is_none()
179 }
180 }
181
182 impl<T> Code<T> for Encoder
183 where
184 T: AsRef<[u8]>,
185 {
186 type Item = Bytes;
187
188 fn code(&mut self, item: T) -> io::Result<Option<Self::Item>> {
189 let encoder = self.0.as_mut().unwrap();
190 encoder.write_all(item.as_ref())?;
191 encoder.flush()?;
192 let b = encoder.get_mut().take();
193 if !b.is_empty() { Ok(Some(b)) } else { Ok(None) }
194 }
195
196 fn code_eof(&mut self) -> io::Result<Option<Self::Item>> {
197 match self.0.take() {
198 Some(encoder) => {
199 let b = encoder.finish()?.take_owned();
200 Ok(Some(b))
201 }
202 None => Ok(None),
203 }
204 }
205
206 #[inline]
207 fn is_end_stream(&self, _: &impl http_body_alt::Body) -> bool {
208 self.0.is_none()
209 }
210 }
211}
212
213pub use self::coder::{Code, Coder, FeaturedCode};
214pub use self::coding::ContentEncoding;
215pub use self::decode::try_decoder;