1use anyhow::Result;
2use flate2::{Compression, CrcReader, CrcWriter};
3
4use crate::RwBuilder;
5
6#[derive(Debug)]
9pub struct CompressionBuilder<B, C>
10where
11 B: RwBuilder,
12 C: CoderBuilder<B::Reader, B::Writer>,
13{
14 builder: B,
16 compression: Compression,
18 coder: C,
20}
21
22impl<B, C> RwBuilder for CompressionBuilder<B, C>
23where
24 B: RwBuilder,
25 B::Reader: std::io::Read,
26 B::Writer: std::io::Write,
27 C: CoderBuilder<B::Reader, B::Writer>,
28 C::Decoder: std::io::Read,
29 C::Encoder: std::io::Write,
30{
31 type Reader = C::Decoder;
32 type Writer = C::Encoder;
33
34 fn reader(&self) -> Result<Self::Reader> {
35 let reader = self.builder.reader()?;
36 Ok(self.coder.decoder(reader))
37 }
38
39 fn writer(&self) -> Result<Self::Writer> {
40 let writer = self.builder.writer()?;
41 Ok(self.coder.encoder(writer, self.compression))
42 }
43}
44
45pub trait CoderBuilder<R, W> {
48 type Encoder;
50
51 fn encoder(&self, writer: W, compression: Compression) -> Self::Encoder;
53
54 type Decoder;
56
57 fn decoder(&self, reader: R) -> Self::Decoder;
59}
60
61#[derive(Default, Debug, Copy, Clone)]
63pub struct Zlib;
64
65impl<R, W> CoderBuilder<R, W> for Zlib
66where
67 R: std::io::Read,
68 W: std::io::Write,
69{
70 type Decoder = flate2::read::ZlibDecoder<R>;
71 type Encoder = flate2::write::ZlibEncoder<W>;
72
73 fn encoder(&self, writer: W, compression: Compression) -> Self::Encoder {
74 flate2::write::ZlibEncoder::new(writer, compression)
75 }
76
77 fn decoder(&self, reader: R) -> Self::Decoder {
78 flate2::read::ZlibDecoder::new(reader)
79 }
80}
81
82pub trait Constructor<B>
84where
85 Self: Sized + CoderBuilder<B::Reader, B::Writer> + Default,
86 B: RwBuilder,
87{
88 fn new(builder: B, compression: Compression) -> CompressionBuilder<B, Self> {
90 CompressionBuilder { builder, compression, coder: Self::default() }
91 }
92}
93
94impl<B> Constructor<B> for Zlib where B: RwBuilder {}
95
96#[derive(Default, Debug, Copy, Clone)]
98pub struct Gz;
99
100impl<R, W> CoderBuilder<R, W> for Gz
101where
102 R: std::io::Read,
103 W: std::io::Write,
104{
105 type Decoder = flate2::read::GzDecoder<R>;
106 type Encoder = flate2::write::GzEncoder<W>;
107
108 fn encoder(&self, writer: W, compression: Compression) -> Self::Encoder {
109 flate2::write::GzEncoder::new(writer, compression)
110 }
111
112 fn decoder(&self, reader: R) -> Self::Decoder {
113 flate2::read::GzDecoder::new(reader)
114 }
115}
116
117impl<B> Constructor<B> for Gz where B: RwBuilder {}
118
119#[derive(Default, Debug, Copy, Clone)]
121pub struct Deflate;
122
123impl<R, W> CoderBuilder<R, W> for Deflate
124where
125 R: std::io::Read,
126 W: std::io::Write,
127{
128 type Decoder = flate2::read::DeflateDecoder<R>;
129 type Encoder = flate2::write::DeflateEncoder<W>;
130
131 fn encoder(&self, writer: W, compression: Compression) -> Self::Encoder {
132 flate2::write::DeflateEncoder::new(writer, compression)
133 }
134
135 fn decoder(&self, reader: R) -> Self::Decoder {
136 flate2::read::DeflateDecoder::new(reader)
137 }
138}
139
140impl<B> Constructor<B> for Deflate where B: RwBuilder {}
141
142#[derive(Debug)]
146pub struct CrcBuilder<B>
147where
148 B: RwBuilder,
149{
150 builder: B,
152}
153
154impl<B> CrcBuilder<B>
155where
156 B: RwBuilder,
157{
158 #[must_use]
160 pub const fn new(builder: B) -> Self {
161 Self { builder }
162 }
163}
164
165impl<B> RwBuilder for CrcBuilder<B>
166where
167 B: RwBuilder,
168 B::Reader: std::io::Read,
169 B::Writer: std::io::Write,
170{
171 type Reader = CrcReader<B::Reader>;
172 type Writer = CrcWriter<B::Writer>;
173
174 fn reader(&self) -> Result<Self::Reader> {
175 Ok(CrcReader::new(self.builder.reader()?))
176 }
177
178 fn writer(&self) -> Result<Self::Writer> {
179 Ok(CrcWriter::new(self.builder.writer()?))
180 }
181}