Skip to content

Commit 7f35b54

Browse files
author
Luca Bruno
authored
Merge pull request #46 from bgilbert/thiserror
Switch from error-chain to thiserror
2 parents fbc52b1 + a7d6bad commit 7f35b54

File tree

3 files changed

+55
-35
lines changed

3 files changed

+55
-35
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "openssh-keys"
3-
version = "0.4.3-alpha.0"
3+
version = "0.5.0-alpha.0"
44
edition = "2018"
55
authors = ["Stephen Demos <stephen@demos.zone>"]
66
description = "read and write OpenSSH public keys"
@@ -18,8 +18,9 @@ base64 = "0.13"
1818
byteorder = "1.1"
1919
md-5 = "0.9"
2020
sha2 = "0.9"
21+
thiserror = "1.0"
2122
# Public dependencies, exposed through library API.
22-
error-chain = { version = "0.12", default-features = false }
23+
# <none>
2324

2425
[dev-dependencies]
2526
dirs = "3.0"

src/lib.rs

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,40 @@
2828
//! }
2929
//! }
3030
31-
#[macro_use]
32-
extern crate error_chain;
33-
3431
mod reader;
3532
mod writer;
3633

3734
pub mod errors {
38-
error_chain! {
39-
foreign_links {
40-
Utf8(::std::str::Utf8Error);
41-
}
42-
errors {
43-
InvalidFormat {
44-
description("invalid key format")
45-
display("invalid key format")
46-
}
47-
UnsupportedKeytype(t: String) {
48-
description("unsupported keytype")
49-
display("unsupported keytype: {}", t)
50-
}
51-
UnsupportedCurve(t: String) {
52-
description("unsupported curve")
53-
display("unsupported curve: {}", t)
54-
}
55-
}
35+
use thiserror::Error;
36+
37+
pub type Result<T> = std::result::Result<T, OpenSSHKeyError>;
38+
39+
#[derive(Error, Debug)]
40+
pub enum OpenSSHKeyError {
41+
#[error("I/O error")]
42+
IO {
43+
#[from]
44+
source: std::io::Error,
45+
},
46+
47+
#[error("invalid UTF-8")]
48+
InvalidUtf8 {
49+
#[from]
50+
source: std::str::Utf8Error,
51+
},
52+
53+
// keep base64::DecodeError out of the public API
54+
#[error("invalid base64: {detail}")]
55+
InvalidBase64 { detail: String },
56+
57+
#[error("invalid key format")]
58+
InvalidFormat,
59+
60+
#[error("unsupported keytype: {keytype}")]
61+
UnsupportedKeyType { keytype: String },
62+
63+
#[error("unsupported curve: {curve}")]
64+
UnsupportedCurve { curve: String },
5665
}
5766
}
5867

@@ -94,7 +103,11 @@ impl Curve {
94103
NISTP_256 => Curve::Nistp256,
95104
NISTP_384 => Curve::Nistp384,
96105
NISTP_521 => Curve::Nistp521,
97-
_ => return Err(ErrorKind::UnsupportedCurve(curve.to_string()).into()),
106+
_ => {
107+
return Err(OpenSSHKeyError::UnsupportedCurve {
108+
curve: curve.to_string(),
109+
})
110+
}
98111
})
99112
}
100113

@@ -161,7 +174,7 @@ impl core::cmp::PartialEq for PublicKey {
161174
}
162175

163176
impl std::str::FromStr for PublicKey {
164-
type Err = Error;
177+
type Err = OpenSSHKeyError;
165178
fn from_str(s: &str) -> Result<Self> {
166179
PublicKey::parse(s)
167180
}
@@ -240,8 +253,8 @@ impl PublicKey {
240253
fn try_key_parse(key: &str) -> Result<Self> {
241254
// then parse the key according to rfc4253
242255
let mut parts = key.split_whitespace();
243-
let keytype = parts.next().ok_or(ErrorKind::InvalidFormat)?;
244-
let data = parts.next().ok_or(ErrorKind::InvalidFormat)?;
256+
let keytype = parts.next().ok_or(OpenSSHKeyError::InvalidFormat)?;
257+
let data = parts.next().ok_or(OpenSSHKeyError::InvalidFormat)?;
245258
// comment is not required. if we get an empty comment (because of a
246259
// trailing space) throw it out.
247260
let comment = parts.next().and_then(|c| {
@@ -252,11 +265,13 @@ impl PublicKey {
252265
}
253266
});
254267

255-
let buf = base64::decode(data).chain_err(|| ErrorKind::InvalidFormat)?;
268+
let buf = base64::decode(data).map_err(|e| OpenSSHKeyError::InvalidBase64 {
269+
detail: format!("{}", e),
270+
})?;
256271
let mut reader = Reader::new(&buf);
257272
let data_keytype = reader.read_string()?;
258273
if keytype != data_keytype {
259-
return Err(ErrorKind::InvalidFormat.into());
274+
return Err(OpenSSHKeyError::InvalidFormat);
260275
}
261276

262277
let data = match keytype {
@@ -327,7 +342,11 @@ impl PublicKey {
327342
key: key.into(),
328343
}
329344
}
330-
_ => return Err(ErrorKind::UnsupportedKeytype(keytype.into()).into()),
345+
_ => {
346+
return Err(OpenSSHKeyError::UnsupportedKeyType {
347+
keytype: keytype.to_string(),
348+
})
349+
}
331350
};
332351

333352
Ok(PublicKey {
@@ -348,10 +367,10 @@ impl PublicKey {
348367
// authorized_keys files are newline-separated lists of public keys
349368
let mut keys = vec![];
350369
for key in keybuf.lines() {
351-
let key = key.chain_err(|| "failed to read public key")?;
370+
let key = key?;
352371
// skip any empty lines and any comment lines (prefixed with '#')
353372
if !key.is_empty() && !(key.trim().starts_with('#')) {
354-
keys.push(PublicKey::parse(&key).chain_err(|| "failed to parse public key")?);
373+
keys.push(PublicKey::parse(&key)?);
355374
}
356375
}
357376
Ok(keys)

src/reader.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ impl<'a> Reader<'a> {
1717
pub fn peek_int(&mut self) -> Result<u32> {
1818
let cur = &self.data[self.offset..];
1919
if cur.len() < 4 {
20-
return Err(ErrorKind::InvalidFormat.into());
20+
return Err(OpenSSHKeyError::InvalidFormat);
2121
}
2222
Ok(BigEndian::read_u32(&cur[..4]))
2323
}
2424

2525
pub fn read_string(&mut self) -> Result<&'a str> {
26-
::std::str::from_utf8(self.read_bytes()?).chain_err(|| ErrorKind::InvalidFormat)
26+
Ok(std::str::from_utf8(self.read_bytes()?)?)
2727
}
2828

2929
pub fn read_mpint(&mut self) -> Result<&'a [u8]> {
@@ -41,7 +41,7 @@ impl<'a> Reader<'a> {
4141
let cur = &self.data[self.offset..];
4242
let len = self.peek_int()? as usize;
4343
if cur.len() < len + 4 {
44-
return Err(ErrorKind::InvalidFormat.into());
44+
return Err(OpenSSHKeyError::InvalidFormat);
4545
}
4646
self.offset += len + 4;
4747
Ok(&cur[4..len + 4])

0 commit comments

Comments
 (0)