1
//! rw-builder provides a convenient way to build `std::io::Read`ers and
2
//! `std::io::Write`rs by chaining transformations. Since readers and writers
3
//! are defined simultaneously through the same builder they can be used as
4
//! inverses of each other.
5
#![deny(
6
    future_incompatible,
7
    nonstandard_style,
8
    rust_2018_compatibility,
9
    rust_2018_idioms,
10
    unused,
11
    warnings
12
)]
13
#![deny(
14
    absolute_paths_not_starting_with_crate,
15
    deprecated_in_future,
16
    elided_lifetimes_in_paths,
17
    explicit_outlives_requirements,
18
    keyword_idents,
19
    macro_use_extern_crate,
20
    meta_variable_misuse,
21
    missing_abi,
22
    missing_copy_implementations,
23
    missing_debug_implementations,
24
    missing_docs,
25
    non_ascii_idents,
26
    noop_method_call,
27
    rust_2021_incompatible_or_patterns,
28
    semicolon_in_expressions_from_macros,
29
    single_use_lifetimes,
30
    trivial_casts,
31
    trivial_numeric_casts,
32
    unreachable_pub,
33
    unsafe_code,
34
    unsafe_op_in_unsafe_fn,
35
    unstable_features,
36
    unused_crate_dependencies,
37
    unused_extern_crates,
38
    unused_import_braces,
39
    unused_lifetimes,
40
    unused_qualifications,
41
    unused_results,
42
    variant_size_differences
43
)]
44
#![deny(
45
    clippy::all,
46
    clippy::cargo,
47
    clippy::nursery,
48
    clippy::pedantic,
49
    clippy::missing_safety_doc,
50
    clippy::missing_docs_in_private_items
51
)]
52
#![deny(
53
    rustdoc::bare_urls,
54
    rustdoc::broken_intra_doc_links,
55
    rustdoc::invalid_codeblock_attributes,
56
    rustdoc::invalid_html_tags,
57
    rustdoc::missing_crate_level_docs,
58
    rustdoc::private_doc_tests,
59
    rustdoc::private_intra_doc_links
60
)]
61

            
62
use anyhow::Result;
63

            
64
/// Provides the `WincodeBuilder` type which acts as a sink to (de)serialize a
65
/// `&[u8]` as wincode.
66
#[cfg(feature = "wincode")]
67
mod wincode;
68
#[cfg(feature = "wincode")]
69
pub use crate::wincode::Builder as WincodeBuilder;
70

            
71
/// Provides the `BufferedBuilder` type which helps build `BufReader` and
72
/// `BufWriter` instances.
73
mod buffered;
74
pub use buffered::Builder as BufferedBuilder;
75

            
76
/// Provides the `FileBuilder` type which acts as a source to read from and
77
/// write to a file.
78
mod file;
79
pub use file::Builder as FileBuilder;
80

            
81
/// Provides several wrapper types around the streaming compression algorithms
82
/// provided by the flate2 crate.
83
#[cfg(feature = "flate2")]
84
mod flate2;
85
#[cfg(feature = "flate2")]
86
pub use ::flate2::Compression;
87

            
88
#[cfg(feature = "flate2")]
89
pub use crate::flate2::{ CompressionBuilder, Constructor, CrcBuilder };
90

            
91
/// Provides the `ProcessBuilder` type which acts as a source to read from
92
/// stdout and write to stdin of a running process.
93
mod process;
94
pub use process::Builder as ProcessBuilder;
95

            
96
/// Provides several wrapper types around the streaming cipher algorithms
97
/// provided by the flate2 crate.
98
#[cfg(any(feature = "chacha20", feature = "salsa20"))]
99
mod stream_cipher;
100
#[cfg(feature = "chacha20")]
101
pub use stream_cipher::{ ChaCha20Builder, ChaCha20Key, ChaCha20Nonce };
102
#[cfg(feature = "salsa20")]
103
pub use stream_cipher::{ Salsa20Builder, Salsa20Key, Salsa20Nonce };
104

            
105
/// Provides the `StringBuilder` type which is a sink without serde
106
mod string;
107
pub use string::AdhocWriter;
108

            
109
/// Provides the `TcpStreamBuilder` type which acts as a source to read from and
110
/// write to a TCP stream.
111
mod tcp_stream;
112
pub use tcp_stream::Builder as TcpStreamBuilder;
113

            
114
/// Provides the `VecBuilder` type which acts as a source to read from and write
115
/// to a memory buffer.
116
mod vec;
117
pub use vec::Builder as VecBuilder;
118

            
119
/// The trait that can construct readers and writers, but also has chainable
120
/// functions to create more complex builders
121
pub trait RwBuilder where Self: Sized, Self::Reader: std::io::Read, Self::Writer: std::io::Write {
122
    /// The reader type that will be constructed by the reader function
123
    type Reader;
124

            
125
    /// Construct a reader from this builder
126
    /// # Errors
127
    /// In case the construction of any of the intermediate readers fails this
128
    /// will return the error associated to the first one that failed.
129
    fn reader(&self) -> Result<Self::Reader>;
130

            
131
    /// The writer type that will be constructed by the reader function
132
    type Writer;
133

            
134
    /// Construct a writer from this builder
135
    /// # Errors
136
    /// In case the construction of any of the intermediate writers fails this
137
    /// will return the error associated to the first one that failed.
138
    fn writer(&self) -> Result<Self::Writer>;
139

            
140
    /// Buffers the underlying readers and writers by wrapping them in a
141
    /// `BufReader` or `BufWriter`
142
1
    fn buffered(self) -> BufferedBuilder<Self> {
143
1
        BufferedBuilder::new(self)
144
1
    }
145

            
146
    /// Sink that provides a bridge between `String` instances and underlying
147
    /// readers and writers.
148
8
    fn string(self) -> string::Builder<Self> {
149
8
        string::Builder::new(self)
150
8
    }
151

            
152
    /// Sink that provides a bridge between serde and the underlying readers and
153
    /// writer by transforming from and to wincode.
154
    #[cfg(feature = "wincode")]
155
1
    fn wincode(self) -> WincodeBuilder<Self> {
156
1
        WincodeBuilder::new(self)
157
1
    }
158

            
159
    /// Transformation that decrypts while reading and encrypts while writing
160
    /// using the chacha20 cipher
161
    #[cfg(feature = "chacha20")]
162
1
    fn chacha20(self, key: ChaCha20Key, nonce: ChaCha20Nonce) -> ChaCha20Builder<Self> {
163
1
        ChaCha20Builder::<Self>::new(self, key, nonce)
164
1
    }
165

            
166
    /// Transformation that decrypts while reading and encrypts while writing
167
    /// using the salsa20 cipher
168
    #[cfg(feature = "salsa20")]
169
1
    fn salsa20(self, key: Salsa20Key, nonce: Salsa20Nonce) -> Salsa20Builder<Self> {
170
1
        Salsa20Builder::<Self>::new(self, key, nonce)
171
1
    }
172

            
173
    /// Non-commutative transformation that hashes using the CRC algorithm
174
    #[cfg(feature = "flate2")]
175
1
    fn crc(self) -> CrcBuilder<Self> {
176
1
        CrcBuilder::new(self)
177
1
    }
178

            
179
    /// Transformation that decompresses while reading and compresses while
180
    /// writing using the Deflate algorithm
181
    #[cfg(feature = "flate2")]
182
1
    fn deflate(self, compression: Compression) -> CompressionBuilder<Self, flate2::Deflate> {
183
1
        flate2::Deflate::new(self, compression)
184
1
    }
185

            
186
    /// Transformation that decompresses while reading and compresses while
187
    /// writing using the Gz algorithm
188
    #[cfg(feature = "flate2")]
189
1
    fn gz(self, compression: Compression) -> CompressionBuilder<Self, flate2::Gz> {
190
1
        flate2::Gz::new(self, compression)
191
1
    }
192

            
193
    /// Transformation that decompresses while reading and compresses while
194
    /// writing using the Zlib algorithm
195
    #[cfg(feature = "flate2")]
196
1
    fn zlib(self, compression: Compression) -> CompressionBuilder<Self, flate2::Zlib> {
197
1
        flate2::Zlib::new(self, compression)
198
1
    }
199
}
200

            
201
/// Trait to wrap serialization and deserialization functionality behind uniform
202
/// load and save functions
203
#[cfg(feature = "wincode")]
204
pub trait SerDe {
205
    /// Deserialize into a specified type
206
    /// # Errors
207
    /// In case the deserialization or the reading fails the return value will
208
    /// contain the first error that occurred.
209
    fn load<T>(&self) -> Result<T> where T: for<'de> serde::de::Deserialize<'de>;
210

            
211
    /// Serialize into the type of the last sink specified
212
    /// # Errors
213
    /// In case the serialization or the writing fails the return value will
214
    /// contain the first error that occurred.
215
    fn save<T>(&self, value: &T) -> Result<()> where T: serde::ser::Serialize;
216
}
217

            
218
#[cfg(test)]
219
mod tests;