diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2018-02-19 12:13:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-19 12:13:06 +0100 |
commit | 97e863f8fb24ae4fda1653d1394bf8f906c58b7d (patch) | |
tree | 149c2425efdf138f00a395bc78e2e6154e1fb132 /lib | |
parent | 7265d598a5a9d8a7a046414d66f88f273879bf5b (diff) | |
parent | b9d04730dbbd71275a240370e3ce55004d22fc69 (diff) |
Merge pull request #1292 from matthiasbeyer/fix-broken-pipes
Fix broken pipes
Diffstat (limited to 'lib')
-rw-r--r-- | lib/core/libimagerror/src/exit.rs | 43 | ||||
-rw-r--r-- | lib/core/libimagerror/src/io.rs | 62 | ||||
-rw-r--r-- | lib/core/libimagerror/src/lib.rs | 2 |
3 files changed, 107 insertions, 0 deletions
diff --git a/lib/core/libimagerror/src/exit.rs b/lib/core/libimagerror/src/exit.rs new file mode 100644 index 00000000..30576b31 --- /dev/null +++ b/lib/core/libimagerror/src/exit.rs @@ -0,0 +1,43 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 the imag contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +pub struct ExitCode(i32); + +impl From<i32> for ExitCode { + fn from(i: i32) -> ExitCode { + ExitCode(i) + } +} + +impl ExitCode { + pub fn code(self) -> i32 { + self.0 + } +} + +pub trait ExitUnwrap<T> { + fn unwrap_or_exit(self) -> T; +} + +impl<T, E: Into<ExitCode>> ExitUnwrap<T> for Result<T, E> { + fn unwrap_or_exit(self) -> T { + self.map_err(Into::into).unwrap_or_else(|e| ::std::process::exit(e.0)) + } +} + diff --git a/lib/core/libimagerror/src/io.rs b/lib/core/libimagerror/src/io.rs new file mode 100644 index 00000000..fff73a61 --- /dev/null +++ b/lib/core/libimagerror/src/io.rs @@ -0,0 +1,62 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2018 the imag contributors +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; version +// 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +// + +use std::io::ErrorKind; + +use exit::ExitCode; + +pub enum Settings { + Ignore(ErrorKind), + IgnoreAny(Vec<ErrorKind>), +} + +pub trait ToExitCode<T> { + fn to_exit_code(self) -> Result<T, ExitCode>; + fn to_exit_code_with(self, Settings) -> Result<T, ExitCode>; +} + +impl<T> ToExitCode<T> for Result<T, ::std::io::Error> { + + /// Returns an exit code of 0 if the error was a broken pipe, else 1 + fn to_exit_code(self) -> Result<T, ExitCode> { + self.to_exit_code_with(Settings::Ignore(ErrorKind::BrokenPipe)) + } + + /// Returns an exit code depending on the settings + /// + /// Via the settings, errors can be ignores (translates to exit code zero). All other errors + /// are translated into exit code 1 + /// + fn to_exit_code_with(self, settings: Settings) -> Result<T, ExitCode> { + self.map_err(move |e| match settings { + Settings::Ignore(kind) => if e.kind() == kind { + 0 + } else { + 1 + }, + Settings::IgnoreAny(v) => if v.iter().any(|el| e.kind() == *el) { + 0 + } else { + 1 + }, + }) + .map_err(ExitCode::from) + } + +} diff --git a/lib/core/libimagerror/src/lib.rs b/lib/core/libimagerror/src/lib.rs index 204250ac..a17aa21e 100644 --- a/lib/core/libimagerror/src/lib.rs +++ b/lib/core/libimagerror/src/lib.rs @@ -37,6 +37,8 @@ extern crate ansi_term; extern crate error_chain; +pub mod io; +pub mod exit; pub mod trace; pub mod iter; pub mod str; |