summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-02-19 12:13:06 +0100
committerGitHub <noreply@github.com>2018-02-19 12:13:06 +0100
commit97e863f8fb24ae4fda1653d1394bf8f906c58b7d (patch)
tree149c2425efdf138f00a395bc78e2e6154e1fb132 /lib
parent7265d598a5a9d8a7a046414d66f88f273879bf5b (diff)
parentb9d04730dbbd71275a240370e3ce55004d22fc69 (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.rs43
-rw-r--r--lib/core/libimagerror/src/io.rs62
-rw-r--r--lib/core/libimagerror/src/lib.rs2
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;