// error.rs // ************************************************************************* // * Copyright (C) 2017-2020 Daniel Mueller (deso@posteo.net) * // * * // * This program is free software: you can redistribute it and/or modify * // * it under the terms of the GNU General Public License as published by * // * the Free Software Foundation, either version 3 of the License, or * // * (at your option) any later version. * // * * // * This program 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 General Public License for more details. * // * * // * You should have received a copy of the GNU General Public License * // * along with this program. If not, see . * // ************************************************************************* use std::fmt; use std::io; use std::str; use std::string; use structopt::clap; /// A trait used to simplify error handling in conjunction with the /// try_with_* functions we use for repeatedly asking the user for a /// secret. pub trait TryInto { fn try_into(self) -> Result; } impl TryInto for T where T: Into, { fn try_into(self) -> Result { Ok(self.into()) } } #[derive(Debug)] pub enum Error { ClapError(clap::Error), IoError(io::Error), NitrokeyError(Option<&'static str>, nitrokey::Error), Utf8Error(str::Utf8Error), Error(String), } impl TryInto for Error { fn try_into(self) -> Result { match self { Error::NitrokeyError(_, err) => Ok(err), err => Err(err), } } } impl From<&str> for Error { fn from(s: &str) -> Error { Error::Error(s.to_string()) } } impl From for Error { fn from(s: String) -> Error { Error::Error(s) } } impl From for Error { fn from(e: clap::Error) -> Error { Error::ClapError(e) } } impl From for Error { fn from(e: nitrokey::Error) -> Error { Error::NitrokeyError(None, e) } } impl From for Error { fn from(e: io::Error) -> Error { Error::IoError(e) } } impl From for Error { fn from(e: str::Utf8Error) -> Error { Error::Utf8Error(e) } } impl From for Error { fn from(e: string::FromUtf8Error) -> Error { Error::Utf8Error(e.utf8_error()) } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Error::ClapError(ref e) => write!(f, "{}", e), Error::NitrokeyError(ref ctx, ref e) => { if let Some(ctx) = ctx { write!(f, "{}: ", ctx)?; } write!(f, "{}", e) } Error::Utf8Error(_) => write!(f, "Encountered UTF-8 conversion error"), Error::IoError(ref e) => write!(f, "IO error: {}", e), Error::Error(ref e) => write!(f, "{}", e), } } }