Skip to main content

rw_builder/
lib.rs

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
62use 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")]
67mod wincode;
68#[cfg(feature = "wincode")]
69pub use crate::wincode::Builder as WincodeBuilder;
70
71/// Provides the `BufferedBuilder` type which helps build `BufReader` and
72/// `BufWriter` instances.
73mod buffered;
74pub 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.
78mod file;
79pub 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")]
84mod flate2;
85#[cfg(feature = "flate2")]
86pub use ::flate2::Compression;
87
88#[cfg(feature = "flate2")]
89pub 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.
93mod process;
94pub 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"))]
99mod stream_cipher;
100#[cfg(feature = "chacha20")]
101pub use stream_cipher::{ChaCha20Builder, ChaCha20Key, ChaCha20Nonce};
102#[cfg(feature = "salsa20")]
103pub use stream_cipher::{Salsa20Builder, Salsa20Key, Salsa20Nonce};
104
105/// Provides the `StringBuilder` type which is a sink without serde
106mod string;
107pub use string::AdhocWriter;
108
109/// Provides the `TcpStreamBuilder` type which acts as a source to read from and
110/// write to a TCP stream.
111mod tcp_stream;
112pub 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.
116mod vec;
117pub 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
121pub trait RwBuilder
122where
123    Self: Sized,
124    Self::Reader: std::io::Read,
125    Self::Writer: std::io::Write,
126{
127    /// The reader type that will be constructed by the reader function
128    type Reader;
129
130    /// Construct a reader from this builder
131    /// # Errors
132    /// In case the construction of any of the intermediate readers fails this
133    /// will return the error associated to the first one that failed.
134    fn reader(&self) -> Result<Self::Reader>;
135
136    /// The writer type that will be constructed by the reader function
137    type Writer;
138
139    /// Construct a writer from this builder
140    /// # Errors
141    /// In case the construction of any of the intermediate writers fails this
142    /// will return the error associated to the first one that failed.
143    fn writer(&self) -> Result<Self::Writer>;
144
145    /// Buffers the underlying readers and writers by wrapping them in a
146    /// `BufReader` or `BufWriter`
147    fn buffered(self) -> BufferedBuilder<Self> {
148        BufferedBuilder::new(self)
149    }
150
151    /// Sink that provides a bridge between `String` instances and underlying
152    /// readers and writers.
153    fn string(self) -> string::Builder<Self> {
154        string::Builder::new(self)
155    }
156
157    /// Sink that provides a bridge between serde and the underlying readers and
158    /// writer by transforming from and to wincode.
159    #[cfg(feature = "wincode")]
160    fn wincode(self) -> WincodeBuilder<Self> {
161        WincodeBuilder::new(self)
162    }
163
164    /// Transformation that decrypts while reading and encrypts while writing
165    /// using the chacha20 cipher
166    #[cfg(feature = "chacha20")]
167    fn chacha20(self, key: ChaCha20Key, nonce: ChaCha20Nonce) -> ChaCha20Builder<Self> {
168        ChaCha20Builder::<Self>::new(self, key, nonce)
169    }
170
171    /// Transformation that decrypts while reading and encrypts while writing
172    /// using the salsa20 cipher
173    #[cfg(feature = "salsa20")]
174    fn salsa20(self, key: Salsa20Key, nonce: Salsa20Nonce) -> Salsa20Builder<Self> {
175        Salsa20Builder::<Self>::new(self, key, nonce)
176    }
177
178    /// Non-commutative transformation that hashes using the CRC algorithm
179    #[cfg(feature = "flate2")]
180    fn crc(self) -> CrcBuilder<Self> {
181        CrcBuilder::new(self)
182    }
183
184    /// Transformation that decompresses while reading and compresses while
185    /// writing using the Deflate algorithm
186    #[cfg(feature = "flate2")]
187    fn deflate(self, compression: Compression) -> CompressionBuilder<Self, flate2::Deflate> {
188        flate2::Deflate::new(self, compression)
189    }
190
191    /// Transformation that decompresses while reading and compresses while
192    /// writing using the Gz algorithm
193    #[cfg(feature = "flate2")]
194    fn gz(self, compression: Compression) -> CompressionBuilder<Self, flate2::Gz> {
195        flate2::Gz::new(self, compression)
196    }
197
198    /// Transformation that decompresses while reading and compresses while
199    /// writing using the Zlib algorithm
200    #[cfg(feature = "flate2")]
201    fn zlib(self, compression: Compression) -> CompressionBuilder<Self, flate2::Zlib> {
202        flate2::Zlib::new(self, compression)
203    }
204}
205
206/// Trait to wrap serialization and deserialization functionality behind uniform
207/// load and save functions
208#[cfg(feature = "wincode")]
209pub trait SerDe {
210    /// Deserialize into a specified type
211    /// # Errors
212    /// In case the deserialization or the reading fails the return value will
213    /// contain the first error that occurred.
214    fn load<T>(&self) -> Result<T>
215    where
216        T: for<'de> serde::de::Deserialize<'de>;
217
218    /// Serialize into the type of the last sink specified
219    /// # Errors
220    /// In case the serialization or the writing fails the return value will
221    /// contain the first error that occurred.
222    fn save<T>(&self, value: &T) -> Result<()>
223    where
224        T: serde::ser::Serialize;
225}
226
227#[cfg(test)]
228mod tests;