diff --git a/Cargo.toml b/Cargo.toml index 5a9b963a..af0cf2ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,3 +55,7 @@ rustc_version = { version = "0.2.2", optional = true } [dev-dependencies] failure_derive = "0.1.1" pretty_env_logger = "0.2.2" + +[[example]] +name = "error-chain-demo" +required-features = ["with_error_chain"] diff --git a/src/client/real.rs b/src/client/real.rs index 10ccd7d2..7828d666 100644 --- a/src/client/real.rs +++ b/src/client/real.rs @@ -87,7 +87,15 @@ impl Default for ClientOptions { } lazy_static! { - static ref CRATE_RE: Regex = Regex::new(r"^([a-zA-Z0-9_]+?)::").unwrap(); + static ref CRATE_RE: Regex = Regex::new(r"^(?:_<)?([a-zA-Z0-9_]+?)(?:\.\.|::)").unwrap(); +} + +/// Tries to parse the rust crate from a function name. +fn parse_crate_name(func_name: &str) -> Option { + CRATE_RE + .captures(func_name) + .and_then(|caps| caps.get(1)) + .map(|cr| cr.as_str().into()) } /// Helper trait to convert an object into a client config @@ -356,10 +364,7 @@ impl Client { // set package if missing to crate prefix if frame.package.is_none() { - frame.package = CRATE_RE - .captures(func_name) - .and_then(|caps| caps.get(1)) - .map(|cr| cr.as_str().into()); + frame.package = parse_crate_name(func_name); } match frame.in_app { @@ -499,3 +504,32 @@ pub fn init(cfg: C) -> ClientInitGuard { client })) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_crate_name() { + assert_eq!( + parse_crate_name("futures::task_impl::std::set"), + Some("futures".into()) + ); + } + + #[test] + fn test_parse_crate_name_impl() { + assert_eq!( + parse_crate_name("_>::enter::_{{closure}}"), + Some("futures".into()) + ); + } + + #[test] + fn test_parse_crate_name_unknown() { + assert_eq!( + parse_crate_name("_>::call_box"), + None + ); + } +}