-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.rs
136 lines (122 loc) · 3.46 KB
/
utils.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use super::writer::Close;
use std::io;
use std::io::Write;
impl<T: Close + ?Sized> Close for &mut T {
#[inline(always)]
fn close(&mut self) -> io::Result<()> {
Close::close(*self)
}
}
impl Close for Vec<u8> {
#[inline(always)]
fn close(&mut self) -> io::Result<()> {
self.flush()
}
}
impl Close for io::Sink {
#[inline(always)]
fn close(&mut self) -> io::Result<()> {
self.flush()
}
}
impl<W: Close + ?Sized> Close for Box<W> {
#[inline(always)]
fn close(&mut self) -> io::Result<()> {
self.as_mut().close()
}
}
impl<W: Write + Close> Close for io::BufWriter<W> {
#[inline]
fn close(&mut self) -> io::Result<()> {
self.flush().and_then(|_| self.get_mut().close())
}
}
impl<W: Write + Close> Close for io::LineWriter<W> {
#[inline]
fn close(&mut self) -> io::Result<()> {
self.flush().and_then(|_| self.get_mut().close())
}
}
/// NopCloser wraps a writer and implements the `Close` trait by
/// performing a `flush` when the `close` method is called. It should
/// only be used to wrap a writer which does not implement the `Close`
/// trait.
///
/// # Examples
///
/// ```
/// use std::{io, io::Write};
/// use sio::{Key, Nonce, Aad, EncWriter, AES_256_GCM, NopCloser};
///
/// // Load your secret keys from a secure location or derive
/// // them using a secure (password-based) key-derivation-function, like Argon2id.
/// // Obviously, don't use this all-zeros key for anything real.
/// let key: Key<AES_256_GCM> = Key::new([0; Key::<AES_256_GCM>::SIZE]);
///
/// // Make sure you use an unique key-nonce combination!
/// // Reusing a nonce value for the same secret key breaks
/// // the security of the encryption algorithm.
/// let nonce = Nonce::new([0; Nonce::<AES_256_GCM>::SIZE]);
///
/// // You must be able to re-generate this aad to decrypt
/// // the ciphertext again. Usually, it's stored together with
/// // the encrypted data.
/// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes());
///
/// let plaintext = "Some example plaintext".as_bytes();
///
/// let mut ciphertext: Vec<u8> = Vec::default(); // Store the ciphertext in memory.
/// let mut writer = EncWriter::new(
/// NopCloser::wrap(io::stdout()), // Without wrapping STDOUT the code would not compile.
/// &key,
/// nonce,
/// aad,
/// );
///
/// writer.write_all(plaintext).expect("There could be your error handling");
///
/// // Complete the encryption process explicitly.
/// writer.close().expect("There could be your error handling");
/// ```
pub struct NopCloser<W: Write>(W);
impl<W: Write> NopCloser<W> {
/// Wraps a writer.
#[inline(always)]
pub fn wrap(w: W) -> Self {
Self(w)
}
}
impl<W: Write> From<W> for NopCloser<W> {
#[inline(always)]
fn from(w: W) -> Self {
Self::wrap(w)
}
}
impl<W: Write> Write for NopCloser<W> {
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
}
impl<W: Write> Close for NopCloser<W> {
#[inline(always)]
fn close(&mut self) -> io::Result<()> {
self.flush()
}
}
impl<W: Write> AsRef<W> for NopCloser<W> {
#[inline(always)]
fn as_ref(&self) -> &W {
&self.0
}
}
impl<W: Write> AsMut<W> for NopCloser<W> {
#[inline(always)]
fn as_mut(&mut self) -> &mut W {
&mut self.0
}
}