Skip to main content

libflate/
finish.rs

1//! `Finish` and related types.
2
3use core::ops::{Deref, DerefMut};
4use no_std_io2::io::{self, Write};
5
6/// `Finish` is a type that represents a value which
7/// may have an error occurred during the computation.
8///
9/// Logically, `Finish<T, E>` is equivalent to `Result<T, (T, E)>`.
10#[derive(Debug, Default, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
11pub struct Finish<T, E> {
12    value: T,
13    error: Option<E>,
14}
15impl<T, E> Finish<T, E> {
16    /// Makes a new instance.
17    ///
18    /// # Examples
19    /// ```
20    /// use libflate::Finish;
21    ///
22    /// // The result value of a succeeded computation
23    /// let succeeded = Finish::new("value", None as Option<()>);
24    /// assert_eq!(succeeded.into_result(), Ok("value"));
25    ///
26    /// // The result value of a failed computation
27    /// let failed = Finish::new("value", Some("error"));
28    /// assert_eq!(failed.into_result(), Err("error"));
29    /// ```
30    pub fn new(value: T, error: Option<E>) -> Self {
31        Finish { value, error }
32    }
33
34    /// Unwraps the instance.
35    ///
36    /// # Examples
37    /// ```
38    /// use libflate::Finish;
39    ///
40    /// let succeeded = Finish::new("value", None as Option<()>);
41    /// assert_eq!(succeeded.unwrap(), ("value", None));
42    ///
43    /// let failed = Finish::new("value", Some("error"));
44    /// assert_eq!(failed.unwrap(), ("value", Some("error")));
45    /// ```
46    pub fn unwrap(self) -> (T, Option<E>) {
47        (self.value, self.error)
48    }
49
50    /// Converts from `Finish<T, E>` to `Result<T, E>`.
51    ///
52    /// # Examples
53    /// ```
54    /// use libflate::Finish;
55    ///
56    /// let succeeded = Finish::new("value", None as Option<()>);
57    /// assert_eq!(succeeded.into_result(), Ok("value"));
58    ///
59    /// let failed = Finish::new("value", Some("error"));
60    /// assert_eq!(failed.into_result(), Err("error"));
61    /// ```
62    pub fn into_result(self) -> Result<T, E> {
63        if let Some(e) = self.error {
64            Err(e)
65        } else {
66            Ok(self.value)
67        }
68    }
69
70    /// Converts from `Finish<T, E>` to `Result<&T, &E>`.
71    ///
72    /// # Examples
73    /// ```
74    /// use libflate::Finish;
75    ///
76    /// let succeeded = Finish::new("value", None as Option<()>);
77    /// assert_eq!(succeeded.as_result(), Ok(&"value"));
78    ///
79    /// let failed = Finish::new("value", Some("error"));
80    /// assert_eq!(failed.as_result(), Err(&"error"));
81    /// ```
82    pub fn as_result(&self) -> Result<&T, &E> {
83        if let Some(ref e) = self.error {
84            Err(e)
85        } else {
86            Ok(&self.value)
87        }
88    }
89}
90
91/// A wrapper struct that completes the processing of the underlying instance when drops.
92///
93/// This calls `Complete:::complete` method of `T` when drops.
94///
95/// # Panics
96///
97/// If the invocation of `Complete::complete(T)` returns an error, `AutoFinish::drop()` will panic.
98#[derive(Debug)]
99pub struct AutoFinish<T: Complete> {
100    inner: Option<T>,
101}
102impl<T: Complete> AutoFinish<T> {
103    /// Makes a new `AutoFinish` instance.
104    ///
105    /// # Examples
106    ///
107    /// ```
108    /// use no_std_io2::io::Write;
109    /// use libflate::finish::AutoFinish;
110    /// use libflate::gzip::Encoder;
111    ///
112    /// let plain = b"Hello World!";
113    /// let mut buf = Vec::new();
114    /// let mut encoder = AutoFinish::new(Encoder::new(&mut buf).unwrap());
115    /// encoder.write_all(plain.as_ref()).unwrap();
116    /// ```
117    pub fn new(inner: T) -> Self {
118        AutoFinish { inner: Some(inner) }
119    }
120
121    /// Unwraps this `AutoFinish` instance, returning the underlying instance.
122    pub fn into_inner(mut self) -> T {
123        self.inner.take().expect("Never fails")
124    }
125}
126impl<T: Complete> Drop for AutoFinish<T> {
127    fn drop(&mut self) {
128        if let Some(inner) = self.inner.take()
129            && let Err(e) = inner.complete()
130        {
131            panic!("{}", e);
132        }
133    }
134}
135impl<T: Complete> Deref for AutoFinish<T> {
136    type Target = T;
137    fn deref(&self) -> &Self::Target {
138        self.inner.as_ref().expect("Never fails")
139    }
140}
141impl<T: Complete> DerefMut for AutoFinish<T> {
142    fn deref_mut(&mut self) -> &mut Self::Target {
143        self.inner.as_mut().expect("Never fails")
144    }
145}
146impl<T: Complete + Write> Write for AutoFinish<T> {
147    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
148        self.deref_mut().write(buf)
149    }
150    fn flush(&mut self) -> io::Result<()> {
151        self.deref_mut().flush()
152    }
153}
154
155/// A wrapper struct that completes the processing of the underlying instance when drops.
156///
157/// This calls `Complete:::complete` method of `T` when drops.
158///
159/// Note that this ignores the result of the invocation of `Complete::complete(T)`.
160#[derive(Debug)]
161pub struct AutoFinishUnchecked<T: Complete> {
162    inner: Option<T>,
163}
164impl<T: Complete> AutoFinishUnchecked<T> {
165    /// Makes a new `AutoFinishUnchecked` instance.
166    ///
167    /// # Examples
168    ///
169    /// ```
170    /// use no_std_io2::io::Write;
171    /// use libflate::finish::AutoFinishUnchecked;
172    /// use libflate::gzip::Encoder;
173    ///
174    /// let plain = b"Hello World!";
175    /// let mut buf = Vec::new();
176    /// let mut encoder = AutoFinishUnchecked::new(Encoder::new(&mut buf).unwrap());
177    /// encoder.write_all(plain.as_ref()).unwrap();
178    /// ```
179    pub fn new(inner: T) -> Self {
180        AutoFinishUnchecked { inner: Some(inner) }
181    }
182
183    /// Unwraps this `AutoFinishUnchecked` instance, returning the underlying instance.
184    pub fn into_inner(mut self) -> T {
185        self.inner.take().expect("Never fails")
186    }
187}
188impl<T: Complete> Drop for AutoFinishUnchecked<T> {
189    fn drop(&mut self) {
190        if let Some(inner) = self.inner.take() {
191            let _ = inner.complete();
192        }
193    }
194}
195impl<T: Complete> Deref for AutoFinishUnchecked<T> {
196    type Target = T;
197    fn deref(&self) -> &Self::Target {
198        self.inner.as_ref().expect("Never fails")
199    }
200}
201impl<T: Complete> DerefMut for AutoFinishUnchecked<T> {
202    fn deref_mut(&mut self) -> &mut Self::Target {
203        self.inner.as_mut().expect("Never fails")
204    }
205}
206impl<T: Complete + Write> Write for AutoFinishUnchecked<T> {
207    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
208        self.deref_mut().write(buf)
209    }
210    fn flush(&mut self) -> io::Result<()> {
211        self.deref_mut().flush()
212    }
213}
214
215/// This trait allows to complete an I/O related processing.
216pub trait Complete {
217    /// Completes the current processing and returns the result.
218    fn complete(self) -> io::Result<()>;
219}