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    pointer_structural_match,
29    semicolon_in_expressions_from_macros,
30    single_use_lifetimes,
31    trivial_casts,
32    trivial_numeric_casts,
33    unreachable_pub,
34    unsafe_code,
35    unsafe_op_in_unsafe_fn,
36    unstable_features,
37    unused_crate_dependencies,
38    unused_extern_crates,
39    unused_import_braces,
40    unused_lifetimes,
41    unused_qualifications,
42    unused_results,
43    variant_size_differences
44)]
45#![deny(
46    clippy::all,
47    clippy::cargo,
48    clippy::nursery,
49    clippy::pedantic,
50    clippy::missing_safety_doc,
51    clippy::missing_docs_in_private_items
52)]
53#![deny(
54    rustdoc::bare_urls,
55    rustdoc::broken_intra_doc_links,
56    rustdoc::invalid_codeblock_attributes,
57    rustdoc::invalid_html_tags,
58    rustdoc::missing_crate_level_docs,
59    rustdoc::private_doc_tests,
60    rustdoc::private_intra_doc_links
61)]
62
63use anyhow::Result;
64
65/// Provides the `BincodeBuilder` type which acts as a sink to (de)serialize a
66/// `&[u8]` as bincode.
67#[cfg(feature = "bincode")]
68mod bincode;
69#[cfg(feature = "bincode")]
70pub use crate::bincode::Builder as BincodeBuilder;
71
72/// Provides the `BufferedBuilder` type which helps build `BufReader` and
73/// `BufWriter` instances.
74mod buffered;
75pub use buffered::Builder as BufferedBuilder;
76
77/// Provides the `FileBuilder` type which acts as a source to read from and
78/// write to a file.
79mod file;
80pub use file::Builder as FileBuilder;
81
82/// Provides several wrapper types around the streaming compression algorithms
83/// provided by the flate2 crate.
84#[cfg(feature = "flate2")]
85mod flate2;
86#[cfg(feature = "flate2")]
87pub use ::flate2::Compression;
88
89#[cfg(feature = "flate2")]
90pub use crate::flate2::{CompressionBuilder, Constructor, CrcBuilder};
91
92/// Provides the `ProcessBuilder` type which acts as a source to read from
93/// stdout and write to stdin of a running process.
94mod process;
95pub use process::Builder as ProcessBuilder;
96
97/// Provides several wrapper types around the streaming cipher algorithms
98/// provided by the flate2 crate.
99#[cfg(any(feature = "chacha20", feature = "salsa20"))]
100mod stream_cipher;
101#[cfg(feature = "chacha20")]
102pub use stream_cipher::{ChaCha20Builder, ChaCha20Key, ChaCha20Nonce};
103#[cfg(feature = "salsa20")]
104pub use stream_cipher::{Salsa20Builder, Salsa20Key, Salsa20Nonce};
105
106/// Provides the `StringBuilder` type which is a sink without serde
107mod string;
108pub use string::AdhocWriter;
109
110/// Provides the `TcpStreamBuilder` type which acts as a source to read from and
111/// write to a TCP stream.
112mod tcp_stream;
113pub use tcp_stream::Builder as TcpStreamBuilder;
114
115/// Provides the `VecBuilder` type which acts as a source to read from and write
116/// to a memory buffer.
117mod vec;
118pub use vec::Builder as VecBuilder;
119
120/// The trait that can construct readers and writers, but also has chainable
121/// functions to create more complex builders
122pub trait RwBuilder
123where
124    Self: Sized,
125    Self::Reader: std::io::Read,
126    Self::Writer: std::io::Write,
127{
128    /// The reader type that will be constructed by the reader function
129    type Reader;
130
131    /// Construct a reader from this builder
132    /// # Errors
133    /// In case the construction of any of the intermediate readers fails this
134    /// will return the error associated to the first one that failed.
135    fn reader(&self) -> Result<Self::Reader>;
136
137    /// The writer type that will be constructed by the reader function
138    type Writer;
139
140    /// Construct a writer from this builder
141    /// # Errors
142    /// In case the construction of any of the intermediate writers fails this
143    /// will return the error associated to the first one that failed.
144    fn writer(&self) -> Result<Self::Writer>;
145
146    /// Buffers the underlying readers and writers by wrapping them in a
147    /// `BufReader` or `BufWriter`
148    fn buffered(self) -> BufferedBuilder<Self> {
149        BufferedBuilder::new(self)
150    }
151
152    /// Sink that provides a bridge between `String` instances and underlying
153    /// readers and writers.
154    fn string(self) -> string::Builder<Self> {
155        string::Builder::new(self)
156    }
157
158    /// Sink that provides a bridge between serde and the underlying readers and
159    /// writer by transforming from and to bincode.
160    #[cfg(feature = "bincode")]
161    fn bincode(self) -> BincodeBuilder<Self> {
162        BincodeBuilder::new(self)
163    }
164
165    /// Transformation that decrypts while reading and encrypts while writing
166    /// using the chacha20 cipher
167    #[cfg(feature = "chacha20")]
168    fn chacha20(self, key: ChaCha20Key, nonce: ChaCha20Nonce) -> ChaCha20Builder<Self> {
169        ChaCha20Builder::<Self>::new(self, key, nonce)
170    }
171
172    /// Transformation that decrypts while reading and encrypts while writing
173    /// using the salsa20 cipher
174    #[cfg(feature = "salsa20")]
175    fn salsa20(self, key: Salsa20Key, nonce: Salsa20Nonce) -> Salsa20Builder<Self> {
176        Salsa20Builder::<Self>::new(self, key, nonce)
177    }
178
179    /// Non-commutative transformation that hashes using the CRC algorithm
180    #[cfg(feature = "flate2")]
181    fn crc(self) -> CrcBuilder<Self> {
182        CrcBuilder::new(self)
183    }
184
185    /// Transformation that decompresses while reading and compresses while
186    /// writing using the Deflate algorithm
187    #[cfg(feature = "flate2")]
188    fn deflate(self, compression: Compression) -> CompressionBuilder<Self, flate2::Deflate> {
189        flate2::Deflate::new(self, compression)
190    }
191
192    /// Transformation that decompresses while reading and compresses while
193    /// writing using the Gz algorithm
194    #[cfg(feature = "flate2")]
195    fn gz(self, compression: Compression) -> CompressionBuilder<Self, flate2::Gz> {
196        flate2::Gz::new(self, compression)
197    }
198
199    /// Transformation that decompresses while reading and compresses while
200    /// writing using the Zlib algorithm
201    #[cfg(feature = "flate2")]
202    fn zlib(self, compression: Compression) -> CompressionBuilder<Self, flate2::Zlib> {
203        flate2::Zlib::new(self, compression)
204    }
205}
206
207/// Trait to wrap serialization and deserialization functionality behind uniform
208/// load and save functions
209#[cfg(feature = "bincode")]
210pub trait SerDe {
211    /// Deserialize into a specified type
212    /// # Errors
213    /// In case the deserialization or the reading fails the return value will
214    /// contain the first error that occurred.
215    fn load<T>(&self) -> Result<T>
216    where
217        T: for<'de> serde::de::Deserialize<'de>;
218
219    /// Serialize into the type of the last sink specified
220    /// # Errors
221    /// In case the serialization or the writing fails the return value will
222    /// contain the first error that occurred.
223    fn save<T>(&self, value: &T) -> Result<()>
224    where
225        T: serde::ser::Serialize;
226}
227
228#[cfg(test)]
229mod tests;