tungstenite/extensions/compression/
mod.rs1use bytes::Bytes;
6use thiserror::Error;
7
8#[cfg(feature = "deflate")]
9pub mod deflate;
10
11#[derive(Debug)]
13#[cfg_attr(not(feature = "deflate"), allow(missing_copy_implementations))] pub enum PerMessageCompressionContext {
15 #[cfg(feature = "deflate")]
17 Deflate(deflate::DeflateContext),
18}
19
20#[derive(Copy, Clone, Debug, Error, PartialEq, Eq)]
22pub enum CompressionError {
23 #[error("Deflate error: {0}")]
25 #[cfg(feature = "deflate")]
26 Deflate(deflate::DeflateError),
27}
28
29#[derive(Debug, Error)]
30#[cfg_attr(test, derive(PartialEq))]
31pub(crate) enum DecompressionError<E = CompressionError> {
32 #[error("decompressed data is too large")]
34 SizeLimitReached,
35 #[error("{0}")]
37 Decompression(E),
38}
39
40impl PerMessageCompressionContext {
41 #[inline]
42 pub(crate) fn compressor<'s>(
43 &'s mut self,
44 ) -> impl FnMut(&Bytes) -> Result<Bytes, CompressionError> + 's {
45 move |payload: &Bytes| match self {
46 #[cfg(feature = "deflate")]
47 Self::Deflate(deflate_config) => {
48 deflate_config.compress(payload).map_err(CompressionError::Deflate)
49 }
50 #[cfg(not(feature = "deflate"))]
51 _ => {
52 let _ = payload;
53 unreachable!("*PerMessageCompressionContext is uninhabited")
54 }
55 }
56 }
57
58 #[inline]
59 pub(crate) fn decompressor<'s>(
60 &'s mut self,
61 ) -> impl FnMut(&Bytes, bool, usize) -> Result<Bytes, DecompressionError> + 's {
62 move |payload, is_final, size_limit| match self {
63 #[cfg(feature = "deflate")]
64 Self::Deflate(deflate_config) => deflate_config
65 .decompress(payload, is_final, size_limit)
66 .map_err(|e| e.map(CompressionError::Deflate)),
67 #[cfg(not(feature = "deflate"))]
68 _ => {
69 let _ = (payload, is_final, size_limit);
70 unreachable!("*PerMessageCompressionContext is uninhabited")
71 }
72 }
73 }
74}
75
76impl<E> DecompressionError<E> {
77 pub(crate) fn map<T>(self, f: impl FnOnce(E) -> T) -> DecompressionError<T> {
78 match self {
79 Self::SizeLimitReached => DecompressionError::SizeLimitReached,
80 Self::Decompression(e) => DecompressionError::Decompression(f(e)),
81 }
82 }
83}
84
85impl<E: Into<std::io::Error>> From<E> for DecompressionError<std::io::Error> {
86 fn from(value: E) -> Self {
87 Self::Decompression(value.into())
88 }
89}