Skip to content

Commit

Permalink
Add #[tracing::instrument] compatibility for #[automock]
Browse files Browse the repository at this point in the history
The mock method won't be instrumented, but at least it will compile.

Fixes #253
  • Loading branch information
asomers committed Feb 13, 2021
1 parent f04c641 commit 8ab7a8c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fixed Clippy warnings in generated code with Rustc 1.52.0.
([#255](https://github.com/asomers/mockall/pull/255))

- Fixed using `#[automock]` with `#[tracing::instrument]`. The mock function
won't be instrumented, but at least it will compile.
([#256](https://github.com/asomers/mockall/pull/256))

### Removed

## [0.9.0] - 2020-12-21
Expand Down
1 change: 1 addition & 0 deletions mockall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ mockall_double = { version = "^0.2.0", path = "../mockall_double" }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
tracing = "0.1.23"

[[example]]
name = "serde"
Expand Down
22 changes: 22 additions & 0 deletions mockall/tests/automock_instrument.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// vim: tw=80
//! A trait that uses tracing::instrument should be automockable. The mock
//! method won't be instrumented, though.
#![deny(warnings)]

use mockall::*;
use tracing::instrument;

#[derive(Debug)]
pub struct Foo {}

#[automock]
impl Foo {
#[instrument]
fn foo(&self) {}
#[instrument]
fn bar() {}
#[tracing::instrument]
fn fooz(&self) {}
#[tracing::instrument]
fn barz() {}
}
29 changes: 18 additions & 11 deletions mockall_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,20 +549,27 @@ impl<'a> AttrFormatter<'a> {

// XXX This logic requires that attributes are imported with their
// standard names.
#[allow(clippy::needless_bool)]
fn format(&mut self) -> Vec<Attribute> {
self.attrs.iter()
.cloned()
.filter(|attr|
( self.doc ||
attr.path.get_ident()
.map(|i| i != "doc")
.unwrap_or(false)
) && (self.async_trait ||
attr.path.get_ident()
.map(|i| i != "async_trait")
.unwrap_or(false)
)
).collect()
.filter(|attr| {
let i = attr.path.get_ident();
if i.is_none() {
false
} else if *i.as_ref().unwrap() == "doc" {
self.doc
} else if *i.as_ref().unwrap() == "async_trait" {
self.async_trait
} else if *i.as_ref().unwrap() == "instrument" {
// We can't usefully instrument the mock method, so just
// ignore this attribute.
// https://docs.rs/tracing/0.1.23/tracing/attr.instrument.html
false
} else {
true
}
}).collect()
}
}

Expand Down

0 comments on commit 8ab7a8c

Please sign in to comment.