Skip to content
Snippets Groups Projects
Commit 18f0fafa authored by Sjoerd Simons's avatar Sjoerd Simons
Browse files

Switch to anyhow for error handling


Use the anyhow crate for error handler to remove a bunch of boilerplate
as well as better error reporting.

Signed-off-by: default avatarSjoerd Simons <sjoerd@collabora.com>
parent 6b02e533
No related branches found
No related tags found
1 merge request!1Wip/sjoerd/multiple files
......@@ -6,6 +6,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"
serde = { version = "1", features = ["derive"] }
serde_json = "1.0"
gimli = "0.16"
......
// Based on the gimli 0.16.1 dwarfdump.rs example
// Allow clippy lints when building without clippy.
use anyhow::{anyhow, Result};
use fallible_iterator::FallibleIterator;
use gimli::{Endianity, Reader};
use object::Object;
use serde::Serialize;
use std::borrow::{Borrow, Cow};
use std::error;
use std::fmt::{self, Debug};
use std::fs;
use std::io;
use std::path::PathBuf;
use std::result;
use structopt::StructOpt;
use typed_arena::Arena;
#[derive(Debug)]
pub enum Error {
GimliError(gimli::Error),
IoError(io::Error),
MissingDIE,
Message(String),
SerdeError(serde_json::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), fmt::Error> {
match self {
Error::GimliError(err) => write!(f, "Gimli error: {}", err),
Error::IoError(e) => write!(f, "I/O error: {}", e),
Error::MissingDIE => write!(f, "Expected a DIE but none was found"),
Error::Message(m) => write!(f, "Error: {}", m),
Error::SerdeError(err) => write!(f, "Serde error: {}", err),
}
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
Error::GimliError(ref err) => Some(err),
Error::SerdeError(ref err) => Some(err),
_ => None,
}
}
}
impl From<gimli::Error> for Error {
fn from(err: gimli::Error) -> Self {
Error::GimliError(err)
}
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error::IoError(e)
}
}
impl From<&str> for Error {
fn from(m: &str) -> Self {
Error::Message(m.to_owned())
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Error::SerdeError(e)
}
}
pub type Result<T> = result::Result<T, Error>;
fn list_file<E: Endianity>(file: &object::File, endian: E) -> Result<Vec<Unit>> {
let arena = Arena::new();
......@@ -140,13 +79,13 @@ fn list_entries<R: Reader>(
.and_then(|attr| attr.string_value(debug_str))
.map::<Result<String>, _>(|s| Ok(s.to_string()?.into_owned()))
.transpose()?
.ok_or("Missing DW_AT_comp_dir")?;
.ok_or_else(|| anyhow!("Missing DW_AT_comp_dir"))?;
let comp_name = entry
.attr(gimli::DW_AT_name)?
.and_then(|attr| attr.string_value(debug_str))
.map::<Result<String>, _>(|s| Ok(s.to_string()?.into_owned()))
.transpose()?
.ok_or("Missing DW_AT_name")?;
.ok_or_else(|| anyhow!("Missing DW_AT_name"))?;
v.push(Unit {
comp_dir,
......@@ -178,7 +117,7 @@ fn main() -> Result<()> {
let opt = Opt::from_args();
let file = fs::File::open(&opt.file)?;
let file = unsafe { memmap::Mmap::map(&file) }?;
let file = object::File::parse(&*file)?;
let file = object::File::parse(&*file).map_err( | e | anyhow!(e))?;
let endian = if file.is_little_endian() {
gimli::RunTimeEndian::Little
......@@ -204,6 +143,7 @@ fn main() -> Result<()> {
} else {
units
};
let d = Data {
file: opt.file,
units,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment