sshkeys/
error.rs

1use std::error::Error as StdError;
2use std::{fmt, io, result, string};
3
4use base64;
5
6/// The `Error` type represents the possible errors that may occur when
7/// working with OpenSSH keys.
8#[derive(Debug)]
9pub struct Error {
10    pub(crate) kind: ErrorKind,
11}
12
13impl Error {
14    pub(crate) fn with_kind(kind: ErrorKind) -> Error {
15        Error { kind: kind }
16    }
17}
18
19/// A type to represent the different kinds of errors.
20#[derive(Debug)]
21pub(crate) enum ErrorKind {
22    Io(io::Error),
23    Decode(base64::DecodeError),
24    Utf8Error(string::FromUtf8Error),
25    InvalidCertType(u32),
26    InvalidFormat,
27    UnexpectedEof,
28    NotCertificate,
29    KeyTypeMismatch,
30    UnknownKeyType(String),
31    UnknownCurve(String),
32}
33
34/// A `Result` type alias where the `Err` variant is `Error`
35pub type Result<T> = result::Result<T, Error>;
36
37impl From<io::Error> for Error {
38    fn from(error: io::Error) -> Error {
39        Error {
40            kind: ErrorKind::Io(error),
41        }
42    }
43}
44
45impl From<base64::DecodeError> for Error {
46    fn from(error: base64::DecodeError) -> Error {
47        Error {
48            kind: ErrorKind::Decode(error),
49        }
50    }
51}
52
53impl From<string::FromUtf8Error> for Error {
54    fn from(error: string::FromUtf8Error) -> Error {
55        Error {
56            kind: ErrorKind::Utf8Error(error),
57        }
58    }
59}
60
61impl StdError for Error {
62    fn source(&self) -> Option<&(dyn StdError + 'static)> {
63        match self.kind {
64            ErrorKind::Io(ref e) => e.source(),
65            ErrorKind::Decode(ref e) => e.source(),
66            ErrorKind::Utf8Error(ref e) => e.source(),
67            ErrorKind::InvalidCertType(_)
68            | ErrorKind::InvalidFormat
69            | ErrorKind::UnexpectedEof
70            | ErrorKind::NotCertificate
71            | ErrorKind::KeyTypeMismatch
72            | ErrorKind::UnknownCurve(_)
73            | ErrorKind::UnknownKeyType(_) => None,
74        }
75    }
76}
77
78impl fmt::Display for Error {
79    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80        match self.kind {
81            ErrorKind::Io(ref err) => err.fmt(f),
82            ErrorKind::Decode(ref err) => err.fmt(f),
83            ErrorKind::Utf8Error(ref err) => err.fmt(f),
84            ErrorKind::InvalidFormat => write!(f, "Invalid format"),
85            ErrorKind::InvalidCertType(v) => write!(f, "Invalid certificate type with value {}", v),
86            ErrorKind::UnexpectedEof => write!(f, "Unexpected EOF reached while reading data"),
87            ErrorKind::UnknownKeyType(ref v) => write!(f, "Unknown key type {}", v),
88            ErrorKind::NotCertificate => write!(f, "Not a certificate"),
89            ErrorKind::KeyTypeMismatch => write!(f, "Key type mismatch"),
90            ErrorKind::UnknownCurve(ref v) => write!(f, "Unknown curve {}", v),
91        }
92    }
93}