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