Skip to main content

rw_builder/
flate2.rs

1use crate::Result;
2use flate2::{Compression, CrcReader, CrcWriter};
3
4use crate::RwBuilder;
5
6/// Type returned by the `deflate`, `gz` and `zlib` functions on the `RwBuilder`
7/// trait. It is itself an `RwBuilder` so can be chained further.
8#[derive(Debug)]
9#[must_use]
10pub struct CompressionBuilder<B, C>
11where
12    B: RwBuilder,
13    C: CoderBuilder<B::Reader, B::Writer>,
14{
15    /// The inner builder it wraps
16    builder: B,
17    /// The compression used for the encoder
18    compression: Compression,
19    /// The builder for the encoder and decoder
20    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
46/// Implementors like `Deflate`, `Gz` and `Zlib` create the associated encoders
47/// and decoders.
48pub trait CoderBuilder<R, W> {
49    /// The type of encoder created
50    type Encoder;
51
52    /// Create an encoder on top of a writer
53    fn encoder(&self, writer: W, compression: Compression) -> Self::Encoder;
54
55    /// The type of decoder created
56    type Decoder;
57
58    /// Create a decoder on top of a reader
59    fn decoder(&self, reader: R) -> Self::Decoder;
60}
61
62/// The Zlib encoder and decoder builder
63#[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
83/// Convenience trait for creating a new encoder/decoder builder
84pub trait Constructor<B>
85where
86    Self: Sized + CoderBuilder<B::Reader, B::Writer> + Default,
87    B: RwBuilder,
88{
89    /// Create the encoder/decoder builder
90    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/// The Gz encoder and decoder builder
98#[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/// The Deflate encoder and decoder builder
121#[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/// Type returned by the `crc` function on the `RwBuilder` trait.
144/// It is itself an `RwBuilder` so can be chained further, although this is an
145/// uncommon scenario
146#[derive(Debug)]
147#[must_use]
148pub struct CrcBuilder<B>
149where
150    B: RwBuilder,
151{
152    /// The inner builder it wraps
153    builder: B,
154}
155
156impl<B> CrcBuilder<B>
157where
158    B: RwBuilder,
159{
160    /// Factory function to wrap an inner builder
161    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}