//! Iterator over recovered data being piped out use crate::pipe_out::WriteLineResult; /// Iterator over recovered data being piped out /// /// The most anticipated error when piping out is a /// [`std::io::ErrorKind::BrokenPipe`] i.e. the program being piped into completes /// it's operation before the data being supplied to this program finishes /// supplying. (See Warning in [`crate::prelude::PipeOut::pipe_out`]) /// /// Example (Dump Data) /// =================== /// /// When an error occurs while piping data out, the most likely desired /// results is simply to return a `Result<(), std::io::Error>` to return to the /// parent function /// /// ```no_run #[doc = include_str!("examples/pipe_out.rs")] /// ``` /// /// Example (Recover Data) /// ====================== /// /// In some scenarios, it may be desireable to recover the data being piped out /// and re-direct it (eg: to a log file). (See Warning in /// [`crate::prelude::PipeOut::pipe_out`]) /// /// ```no_run #[doc = include_str!("examples/example_handles_broken_pipe.rs")] /// ``` pub struct PipeOutRecoveredIterator> { /// The iterator being piped out pub iter: I, /// Datum being piped out when error occurred pub recovered_datum: Option, /// Result of last [`pipe_out`][crate::pipe_out::PipeOut::pipe_out] pub result: WriteLineResult, } impl> Iterator for PipeOutRecoveredIterator { type Item = D; fn next(&mut self) -> Option { self.recovered_datum.take().or_else(|| self.iter.next()) } } impl> PipeOutRecoveredIterator { /// Return [`WriteLineResult`], Ignore recovered data /// /// # Example /// /// ``` /// # use std_io_iterators::prelude::*; /// # const RESULT: WriteLineResult = WriteLineResult::PreviousError; /// # let iter = [""].into_iter(); /// // GIVEN /// let recovered_iterator = PipeOutRecoveredIterator { /// iter, /// # recovered_datum: None, /// result: RESULT, /// // ... /// }; /// /// // WHEN /// let actual = recovered_iterator.dump_data(); /// /// // THEN /// assert!(actual.same_variant_as(&RESULT)); /// ``` pub fn dump_data(self) -> WriteLineResult { self.result } /// Return if error contained is broken pipe error pub fn is_broken_pipe(&self) -> bool { matches!(self.result, WriteLineResult::BrokenPipe(_)) } /// Return if contains recovered datum /// /// # Example /// /// See [`PipeOutRecoveredIterator::take_recovered_datum`] pub fn has_recovered_datum(&self) -> bool { self.recovered_datum.is_some() } /// Return recovered datum (if present) /// /// Example /// ======= /// /// ``` /// # use std_io_iterators::prelude::*; /// # const DUMMY_RECOVERED_DATUM: &str = "Test1655350169"; /// # let iter = [String::new()].into_iter(); /// // GIVEN /// let mut result = PipeOutRecoveredIterator { /// # iter, /// recovered_datum: Some(DUMMY_RECOVERED_DATUM.to_owned()), /// # result: WriteLineResult::Ok, /// // ... /// }; /// assert!(result.has_recovered_datum()); /// /// // WHEN /// let actual = result.take_recovered_datum(); /// /// // THEN /// assert_eq!(actual, Some(DUMMY_RECOVERED_DATUM.to_owned())); /// assert!(!result.has_recovered_datum()); /// ``` pub fn take_recovered_datum(&mut self) -> Option { self.recovered_datum.take() } }