diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 1699 |
1 files changed, 1699 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..121fff3 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,1699 @@ +// vim: tw=80 +//! A powerful mock object library for Rust. +//! +//! Mockall provides tools to create mock versions of almost any trait +//! or struct. They can be used in unit tests as a stand-in for the real +//! object. +//! +//! # Usage +//! +//! There are two ways to use Mockall. The easiest is to use +//! [`#[automock]`](attr.automock.html). It can mock most traits, or structs +//! that only have a single `impl` block. For things it can't handle, there is +//! [`mock!`]. +//! +//! Whichever method is used, the basic idea is the same. +//! * Create a mock struct. It's name will be the same as the original, with +//! "Mock" prepended. +//! * In your test, instantiate the mock struct with its `new` or `default` +//! method. +//! * Set expectations on the mock struct. Each expectation can have required +//! argument matchers, a required call count, and a required position in a +//! [`Sequence`]. Each expectation must also have a return value. +//! * Supply the mock object to the code that you're testing. It will return +//! the preprogrammed return values supplied in the previous step. Any +//! accesses contrary to your expectations will cause a panic. +//! +//! # User Guide +//! +//! * [`Getting started`](#getting-started) +//! * [`Static Return values`](#static-return-values) +//! * [`Matching arguments`](#matching-arguments) +//! * [`Call counts`](#call-counts) +//! * [`Sequences`](#sequences) +//! * [`Checkpoints`](#checkpoints) +//! * [`Reference arguments`](#reference-arguments) +//! * [`Reference return values`](#reference-return-values) +//! * [`impl Trait`](#impl-trait) +//! * [`Mocking structs`](#mocking-structs) +//! * [`Generic methods`](#generic-methods) +//! * [`Methods with generic lifetimes`](#methods-with-generic-lifetimes) +//! * [`Generic traits and structs`](#generic-traits-and-structs) +//! * [`Associated types`](#associated-types) +//! * [`Multiple and inherited traits`](#multiple-and-inherited-traits) +//! * [`External traits`](#external-traits) +//! * [`Static methods`](#static-methods) +//! * [`Modules`](#modules) +//! * [`Foreign functions`](#foreign-functions) +//! * [`Debug`](#debug) +//! * [`Async Traits`](#async-traits) +//! * [`Crate features`](#crate-features) +//! * [`Examples`](#examples) +//! +//! ## Getting Started +//! ``` +//! use mockall::*; +//! use mockall::predicate::*; +//! #[automock] +//! trait MyTrait { +//! fn foo(&self, x: u32) -> u32; +//! } +//! +//! fn call_with_four(x: &MyTrait) -> u32 { +//! x.foo(4) +//! } +//! +//! let mut mock = MockMyTrait::new(); +//! mock.expect_foo() +//! .with(predicate::eq(4)) +//! .times(1) +//! .returning(|x| x + 1); +//! assert_eq!(5, call_with_four(&mock)); +//! ``` +//! +//! ## Static Return values +//! +//! Every expectation must have an associated return value (though when the +//! **nightly** feature is enabled expectations will automatically return the +//! default values of their return types, if their return types implement +//! `Default`.). For methods that return a `static` value, the macros will +//! generate an `Expectation` struct like +//! [`this`](examples::__mock_MockFoo_Foo::__foo::Expectation). +//! There are two ways to set such an expectation's return value: with a +//! constant +//! ([`return_const`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_const)) +//! or a closure +//! ([`returning`](examples::__mock_MockFoo_Foo::__foo::Expectation::returning)). +//! A closure will take the method's arguments by value. +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! trait MyTrait { +//! fn foo(&self) -> u32; +//! fn bar(&self, x: u32, y: u32) -> u32; +//! } +//! +//! let mut mock = MockMyTrait::new(); +//! mock.expect_foo() +//! .return_const(42u32); +//! mock.expect_bar() +//! .returning(|x, y| x + y); +//! ``` +//! +//! Additionally, constants that aren't `Clone` can be returned with the +//! [`return_once`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_once) +//! method. +//! +//! ``` +//! # use mockall::*; +//! struct NonClone(); +//! #[automock] +//! trait Foo { +//! fn foo(&self) -> NonClone; +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! let r = NonClone{}; +//! mock.expect_foo() +//! .return_once(move || r); +//! # } +//! ``` +//! +//! `return_once` can also be used for computing the return value with an +//! `FnOnce` closure. This is useful for returning a non-`Clone` value and also +//! triggering side effects at the same time. +//! +//! ``` +//! # use mockall::*; +//! fn do_something() {} +//! +//! struct NonClone(); +//! +//! #[automock] +//! trait Foo { +//! fn foo(&self) -> NonClone; +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! let r = NonClone{}; +//! mock.expect_foo() +//! .return_once(move || { +//! do_something(); +//! r +//! }); +//! # } +//! ``` +//! +//! Mock objects are always `Send`. If you need to use a return type that +//! isn't, you can use the +//! [`return_const_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_const_st), +//! [`returning_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::returning_st), +//! or +//! [`return_once_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::return_once_st), +//! methods. If you need to match arguments that are not `Send`, you can use the +//! [`withf_st`](examples::__mock_MockFoo_Foo::__foo::Expectation::withf_st) +//! These take a non-`Send` object and add runtime access checks. The wrapped +//! object will be `Send`, but accessing it from multiple threads will cause a +//! runtime panic. +//! +//! ``` +//! # use mockall::*; +//! # use std::rc::Rc; +//! #[automock] +//! trait Foo { +//! fn foo(&self, x: Rc<u32>) -> Rc<u32>; // Rc<u32> isn't Send +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! let x = Rc::new(5); +//! let argument = x.clone(); +//! mock.expect_foo() +//! .withf_st(move |x| *x == argument) +//! .returning_st(move |_| Rc::new(42u32)); +//! assert_eq!(42, *mock.foo(x)); +//! # } +//! ``` +//! +//! ## Matching arguments +//! +//! Optionally, expectations may have argument matchers set. A matcher will +//! verify that the expectation was called with the expected arguments, or panic +//! otherwise. A matcher is anything that implements the [`Predicate`] trait. +//! For example: +//! +//! ```should_panic +//! # use mockall::*; +//! # use mockall::predicate::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self, x: u32); +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .with(eq(42)) +//! .return_const(()); +//! +//! mock.foo(0); // Panics! +//! ``` +//! +//! See [`predicate`] for a list of Mockall's builtin predicate functions. +//! For convenience, +//! [`withf`](examples::__mock_MockFoo_Foo::__foo::Expectation::withf) +//! is a shorthand for setting the commonly used +//! [`function`] predicate. The arguments to the predicate function are the +//! method's arguments, *by reference*. For example: +//! +//! ```should_panic +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self, x: u32, y: u32); +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .withf(|x: &u32, y: &u32| x == y) +//! .return_const(()); +//! +//! mock.foo(2 + 2, 5); // Panics! +//! # } +//! ``` +//! +//! ### Matching multiple calls +//! +//! Matchers can also be used to discriminate between different invocations of +//! the same function. Used that way, they can provide different return values +//! for different arguments. The way this works is that on a method call, all +//! expectations set on a given method are evaluated in FIFO order. The first +//! matching expectation is used. Only if none of the expectations match does +//! Mockall panic. For example: +//! +//! ``` +//! # use mockall::*; +//! # use mockall::predicate::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self, x: u32) -> u32; +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .with(eq(5)) +//! .return_const(50u32); +//! mock.expect_foo() +//! .with(eq(6)) +//! .return_const(60u32); +//! # } +//! ``` +//! +//! One common pattern is to use multiple expectations in order of decreasing +//! specificity. The last expectation can provide a default or fallback value, +//! and earlier ones can be more specific. For example: +//! +//! ``` +//! # use mockall::*; +//! # use mockall::predicate::*; +//! #[automock] +//! trait Foo { +//! fn open(&self, path: String) -> Option<u32>; +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_open() +//! .with(eq(String::from("something.txt"))) +//! .returning(|_| Some(5)); +//! mock.expect_open() +//! .return_const(None); +//! ``` +//! +//! ## Call counts +//! +//! By default, every expectation is allowed to be called an unlimited number of +//! times. But Mockall can optionally verify that an expectation was called a +//! fixed number of times, or any number of times within a given range. +//! +//! ```should_panic +//! # use mockall::*; +//! # use mockall::predicate::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self, x: u32); +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .times(1) +//! .return_const(()); +//! +//! mock.foo(0); // Ok +//! mock.foo(1); // Panics! +//! ``` +//! +//! See also +//! [`never`](examples::__mock_MockFoo_Foo::__foo::Expectation::never) and +//! [`times`](examples::__mock_MockFoo_Foo::__foo::Expectation::times). +//! +//! ## Sequences +//! +//! By default expectations may be matched in any order. But it's possible to +//! specify the order by using a [`Sequence`]. Any expectations may be added to +//! the same sequence. They don't even need to come from the same object. +//! +//! ```should_panic(expected = "Method sequence violation") +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self); +//! } +//! +//! # fn main() { +//! let mut seq = Sequence::new(); +//! +//! let mut mock1 = MockFoo::new(); +//! mock1.expect_foo() +//! .times(1) +//! .in_sequence(&mut seq) +//! .returning(|| ()); +//! +//! let mut mock2 = MockFoo::new(); +//! mock2.expect_foo() +//! .times(1) +//! .in_sequence(&mut seq) +//! .returning(|| ()); +//! +//! mock2.foo(); // Panics! mock1.foo should've been called first. +//! # } +//! ``` +//! +//! ## Checkpoints +//! +//! Sometimes its useful to validate all expectations mid-test, throw them away, +//! and add new ones. That's what checkpoints do. Every mock object has a +//! `checkpoint` method. When called, it will immediately validate all methods' +//! expectations. So any expectations that haven't satisfied their call count +//! will panic. Afterwards, those expectations will be cleared so you can add +//! new expectations and keep testing. +//! +//! ```should_panic +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self); +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .times(2) +//! .returning(|| ()); +//! +//! mock.foo(); +//! mock.checkpoint(); // Panics! foo hasn't yet been called twice. +//! ``` +//! +//! ```should_panic +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self); +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .times(1) +//! .returning(|| ()); +//! +//! mock.foo(); +//! mock.checkpoint(); +//! mock.foo(); // Panics! The expectation has been cleared. +//! # } +//! ``` +//! +//! ## Reference arguments +//! +//! Mockall can mock methods with reference arguments, too. There's one catch: +//! the matcher [`Predicate`] will take reference arguments by value, not by +//! reference. +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self, x: &u32) -> u32; +//! } +//! +//! let mut mock = MockFoo::new(); +//! let e = mock.expect_foo() +//! // Note that x is a &u32, not a &&u32 +//! .withf(|x: &u32| *x == 5) +//! .returning(|x: &u32| *x + 1); +//! +//! assert_eq!(6, mock.foo(&5)); +//! ``` +//! +//! ## Reference return values +//! +//! Mockall can also use reference return values. There is one restriction: the +//! lifetime of the returned reference must be either the same as the lifetime +//! of the mock object, or `'static`. +//! +//! Mockall creates different expectation types for methods that return +//! references. Their API is the same as the basic `Expectation`, except for +//! setting return values. +//! +//! Methods that return `'static` references work just like methods that return +//! any other `'static` value. +//! ``` +//! # use mockall::*; +//! struct Thing(u32); +//! +//! #[automock] +//! trait Container { +//! fn get(&self, i: u32) -> &'static Thing; +//! } +//! +//! # fn main() { +//! const THING: Thing = Thing(42); +//! let mut mock = MockContainer::new(); +//! mock.expect_get() +//! .return_const(&THING); +//! +//! assert_eq!(42, mock.get(0).0); +//! # } +//! ``` +//! +//! Methods that take a `&self` argument use an `Expectation` class like +//! [this](examples::__mock_MockFoo_Foo::__bar::Expectation), +//! which +//! gets its return value from the +//! [`return_const`](examples::__mock_MockFoo_Foo::__bar::Expectation::return_const) method. +//! +//! ``` +//! # use mockall::*; +//! struct Thing(u32); +//! +//! #[automock] +//! trait Container { +//! fn get(&self, i: u32) -> &Thing; +//! } +//! +//! # fn main() { +//! let thing = Thing(42); +//! let mut mock = MockContainer::new(); +//! mock.expect_get() +//! .return_const(thing); +//! +//! assert_eq!(42, mock.get(0).0); +//! # } +//! ``` +//! +//! Methods that take a `&mut self` argument use an `Expectation` class like +//! [this](examples::__mock_MockFoo_Foo::__baz::Expectation), +//! class, regardless of whether the return value is actually mutable. They can +//! take their return value either from the +//! [`return_var`](examples::__mock_MockFoo_Foo::__baz::Expectation::return_var) +//! or +//! [`returning`](examples::__mock_MockFoo_Foo::__baz::Expectation::returning) +//! methods. +//! +//! ``` +//! # use mockall::*; +//! struct Thing(u32); +//! +//! #[automock] +//! trait Container { +//! fn get_mut(&mut self, i: u32) -> &mut Thing; +//! } +//! +//! # fn main() { +//! let thing = Thing(42); +//! let mut mock = MockContainer::new(); +//! mock.expect_get_mut() +//! .return_var(thing); +//! +//! mock.get_mut(0).0 = 43; +//! assert_eq!(43, mock.get_mut(0).0); +//! # } +//! ``` +//! +//! Unsized types that are common targets for +//! [`Deref`](core::ops::Deref) +//! are special. Mockall +//! will automatically use the type's owned form for the Expectation. +//! Currently, the +//! [`CStr`](std::ffi::CStr), +//! [`OsStr`](std::ffi::OsStr), +//! [`Path`](std::path::Path), +//! [`Slice`][std::slice], +//! and +//! [`str`](std::str) +//! types are supported. Using this feature is automatic: +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn name(&self) -> &str; +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_name().return_const("abcd".to_owned()); +//! assert_eq!("abcd", mock.name()); +//! ``` +//! +//! Similarly, Mockall will use a Boxed trait object for the Expectation of +//! methods that return references to trait objects. +//! +//! ``` +//! # use mockall::*; +//! # use std::fmt::Display; +//! #[automock] +//! trait Foo { +//! fn name(&self) -> &dyn Display; +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_name().return_const(Box::new("abcd")); +//! assert_eq!("abcd", format!("{}", mock.name())); +//! # } +//! ``` +//! +//! +//! ## Impl Trait +//! +//! Rust 1.26.0 introduced the `impl Trait` feature. It allows functions to +//! return concrete but unnamed types (and, less usefully, to take them as +//! arguments). It's *almost* the same as `Box<dyn Trait>` but without the +//! extra allocation. Mockall supports deriving mocks for methods that return +//! `impl Trait`, with limitations. When you derive the mock for such a method, +//! Mockall internally transforms the Expectation's return type to `Box<dyn +//! Trait>`, without changing the mock method's signature. So you can use it +//! like this: +//! +//! ``` +//! # use mockall::*; +//! # use std::fmt::Debug; +//! struct Foo {} +//! #[automock] +//! impl Foo { +//! fn foo(&self) -> impl Debug { +//! // ... +//! # 4 +//! } +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .returning(|| Box::new(String::from("Hello, World!"))); +//! println!("{:?}", mock.foo()); +//! # } +//! ``` +//! +//! However, `impl Trait` isn't *exactly* equivalent to `Box<dyn Trait>` but +//! with fewer allocations. There are some things the former can do but the +//! latter can't. For one thing, you can't build a trait object out of a +//! `Sized` trait. So this won't work: +//! +//! ```compile_fail +//! # use mockall::*; +//! struct Foo {} +//! #[automock] +//! impl Foo { +//! fn foo(&self) -> impl Clone { +//! // ... +//! # 4 +//! } +//! } +//! ``` +//! +//! Nor can you create a trait object that implements two or more non-auto +//! types. So this won't work either: +//! +//! ```compile_fail +//! # use mockall::*; +//! struct Foo {} +//! #[automock] +//! impl Foo { +//! fn foo(&self) -> impl Debug + Display { +//! // ... +//! # 4 +//! } +//! } +//! ``` +//! +//! For such cases, there is no magic bullet. The best way to mock methods like +//! those would be to refactor them to return named (but possibly opaque) types +//! instead. +//! +//! See Also [`impl-trait-for-returning-complex-types-with-ease.html`](https://rust-lang-nursery.github.io/edition-guide/rust-2018/trait-system/impl-trait-for-returning-complex-types-with-ease) +//! +//! ### impl Future +//! +//! Rust 1.36.0 added the `Future` trait. Unlike virtually every trait that +//! preceeded it, `Box<dyn Future>` is mostly useless. Instead, you usually +//! need a `Pin<Box<dyn Future>>`. So that's what Mockall will do when you mock +//! a method returning `impl Future` or the related `impl Stream`. Just +//! remember to use `pin` in your expectations, like this: +//! +//! ``` +//! # use mockall::*; +//! # use std::fmt::Debug; +//! # use futures::{Future, future}; +//! struct Foo {} +//! #[automock] +//! impl Foo { +//! fn foo(&self) -> impl Future<Output=i32> { +//! // ... +//! # future::ready(42) +//! } +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .returning(|| Box::pin(future::ready(42))); +//! # } +//! ``` +//! +//! ## Mocking structs +//! +//! Mockall mocks structs as well as traits. The problem here is a namespace +//! problem: it's hard to supply the mock object to your code under test, +//! because it has a different name. The solution is to alter import paths +//! during test. The easiest way to do that is with the +//! [`mockall_double`](https://docs.rs/mockall_double/latest) crate. +//! +//! [`#[automock]`](attr.automock.html) +//! works for structs that have a single `impl` block: +//! ```no_run +//! use mockall_double::double; +//! mod thing { +//! use mockall::automock; +//! pub struct Thing{} +//! #[automock] +//! impl Thing { +//! pub fn foo(&self) -> u32 { +//! // ... +//! # unimplemented!() +//! } +//! } +//! } +//! +//! #[double] +//! use thing::Thing; +//! +//! fn do_stuff(thing: &Thing) -> u32 { +//! thing.foo() +//! } +//! +//! #[cfg(test)] +//! mod t { +//! use super::*; +//! +//! #[test] +//! fn test_foo() { +//! let mut mock = Thing::default(); +//! mock.expect_foo().returning(|| 42); +//! do_stuff(&mock); +//! } +//! } +//! # fn main() {} +//! ``` +//! For structs with more than one `impl` block or that have unsupported +//! `#[derive(X)]` attributes, e.g. `Clone`, see [`mock!`] instead. +//! +//! ## Generic methods +//! +//! Generic methods can be mocked, too. Effectively each generic method is an +//! infinite set of regular methods, and each of those works just like any other +//! regular method. The expect_* method is generic, too, and usually must be +//! called with a turbofish. The only restrictions on mocking generic methods +//! are that all generic parameters must be `'static`, and generic lifetime +//! parameters are not allowed. +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo<T: 'static>(&self, t: T) -> i32; +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_foo::<i16>() +//! .returning(|t| i32::from(t)); +//! mock.expect_foo::<i8>() +//! .returning(|t| -i32::from(t)); +//! +//! assert_eq!(5, mock.foo(5i16)); +//! assert_eq!(-5, mock.foo(5i8)); +//! ``` +//! +//! ## Methods with generic lifetimes +//! +//! A method with a lifetime parameter is technically a generic method, but +//! Mockall treats it like a non-generic method that must work for all possible +//! lifetimes. Mocking such a method is similar to mocking a non-generic +//! method, with a few additional restrictions. One restriction is that you +//! can't match calls with `with`, you must use `withf` instead. Another is +//! that the generic lifetime may not appear as part of the return type. +//! Finally, no method may have both generic lifetime parameters *and* generic +//! type parameters. +//! +//! ``` +//! # use mockall::*; +//! struct X<'a>(&'a i32); +//! +//! #[automock] +//! trait Foo { +//! fn foo<'a>(&self, x: X<'a>) -> i32; +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::new(); +//! mock.expect_foo() +//! .withf(|f| *f.0 == 5) +//! .return_const(42); +//! let x = X(&5); +//! assert_eq!(42, mock.foo(x)); +//! # } +//! ``` +//! +//! ## Generic traits and structs +//! +//! Mocking generic structs and generic traits is not a problem. The mock +//! struct will be generic, too. The same restrictions apply as with mocking +//! generic methods: each generic parameter must be `'static`, and generic +//! lifetime parameters are not allowed. +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! trait Foo<T: 'static> { +//! fn foo(&self, t: T) -> i32; +//! } +//! +//! # fn main() { +//! let mut mock = MockFoo::<i16>::new(); +//! mock.expect_foo() +//! .returning(|t| i32::from(t)); +//! assert_eq!(5, mock.foo(5i16)); +//! # } +//! ``` +//! +//! ## Associated types +//! +//! Traits with associated types can be mocked too. Unlike generic traits, the +//! mock struct will not be generic. Instead, you must specify the associated +//! types when defining the mock struct. They're specified as metaitems to the +//! [`#[automock]`](attr.automock.html) attribute. +//! +//! ``` +//! # use mockall::*; +//! #[automock(type Key=u16; type Value=i32;)] +//! pub trait A { +//! type Key; +//! type Value; +//! fn foo(&self, k: Self::Key) -> Self::Value; +//! } +//! +//! let mut mock = MockA::new(); +//! mock.expect_foo() +//! .returning(|x: u16| i32::from(x)); +//! assert_eq!(4, mock.foo(4)); +//! ``` +//! +//! ## Multiple and inherited traits +//! +//! Creating a mock struct that implements multiple traits, whether inherited or +//! not, requires using the [`mock!`] macro. But once created, +//! using it is just the same as using any other mock object: +//! +//! ``` +//! # use mockall::*; +//! pub trait A { +//! fn foo(&self); +//! } +//! +//! pub trait B: A { +//! fn bar(&self); +//! } +//! +//! mock! { +//! // Structure to mock +//! C {} +//! // First trait to implement on C +//! impl A for C { +//! fn foo(&self); +//! } +//! // Second trait to implement on C +//! impl B for C { +//! fn bar(&self); +//! } +//! } +//! # fn main() { +//! let mut mock = MockC::new(); +//! mock.expect_foo().returning(|| ()); +//! mock.expect_bar().returning(|| ()); +//! mock.foo(); +//! mock.bar(); +//! # } +//! ``` +//! +//! ## External traits +//! +//! Mockall can mock traits and structs defined in external crates that are +//! beyond your control, but you must use [`mock!`] instead of +//! [`#[automock]`](attr.automock.html). Mock an external trait like this: +//! +//! ``` +//! # use mockall::*; +//! mock! { +//! MyStruct {} // Name of the mock struct, less the "Mock" prefix +//! impl Clone for MyStruct { // specification of the trait to mock +//! fn clone(&self) -> Self; +//! } +//! } +//! +//! # fn main() { +//! let mut mock1 = MockMyStruct::new(); +//! let mock2 = MockMyStruct::new(); +//! mock1.expect_clone() +//! .return_once(move || mock2); +//! let cloned = mock1.clone(); +//! # } +//! ``` +//! +//! ## Static methods +//! +//! Mockall can also mock static methods. But be careful! The expectations are +//! global. If you want to use a static method in multiple tests, you must +//! provide your own synchronization. See the [`synchronization +//! example`](https://github.com/asomers/mockall/blob/master/mockall/examples/synchronization.rs) +//! for a basic implementation. For ordinary methods, expectations are +//! set on the mock object. But static methods don't have any mock object. +//! Instead, you must create a `Context` object just to set their expectations. +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! pub trait A { +//! fn foo() -> u32; +//! } +//! +//! let ctx = MockA::foo_context(); +//! ctx.expect().returning(|| 99); +//! assert_eq!(99, MockA::foo()); +//! ``` +//! +//! A common pattern is mocking a trait with a constructor method. In this case, +//! you can easily set the mock constructor method to return a mock object. +//! +//! ``` +//! # use mockall::*; +//! struct Foo{} +//! #[automock] +//! impl Foo { +//! fn from_i32(x: i32) -> Self { +//! // ... +//! # unimplemented!() +//! } +//! fn foo(&self) -> i32 { +//! // ... +//! # unimplemented!() +//! } +//! } +//! +//! # fn main() { +//! let ctx = MockFoo::from_i32_context(); +//! ctx.expect() +//! .returning(|x| { +//! let mut mock = MockFoo::default(); +//! mock.expect_foo() +//! .return_const(x); +//! mock +//! }); +//! let foo = MockFoo::from_i32(42); +//! assert_eq!(42, foo.foo()); +//! # } +//! ``` +//! +//! ### Generic static methods +//! +//! Mocking static methods of generic structs or traits, whether or not the +//! methods themselves are generic, should work seamlessly. +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! trait Foo<T: 'static> { +//! fn new(t: T) -> MockFoo<T>; +//! } +//! +//! # fn main() { +//! let ctx = MockFoo::<u32>::new_context(); +//! ctx.expect() +//! .returning(|_| MockFoo::default()); +//! let mock = MockFoo::<u32>::new(42u32); +//! # } +//! ``` +//! +//! ### Context checkpoints +//! +//! The context object cleans up all expectations when it leaves scope. It also +//! has a `checkpoint` method that functions just like a mock object's +//! `checkpoint` method. +//! +//! ```should_panic +//! # use mockall::*; +//! #[automock] +//! pub trait A { +//! fn foo() -> u32; +//! } +//! +//! let ctx = MockA::foo_context(); +//! ctx.expect() +//! .times(1) +//! .returning(|| 99); +//! ctx.checkpoint(); // Panics! +//! ``` +//! +//! A mock object's checkpoint method does *not* checkpoint static methods. +//! This behavior is useful when using multiple mock objects at once. For +//! example: +//! +//! ``` +//! # use mockall::*; +//! #[automock] +//! pub trait A { +//! fn build() -> Self; +//! fn bar(&self) -> i32; +//! } +//! +//! # fn main() { +//! let ctx = MockA::build_context(); +//! ctx.expect() +//! .times(2) +//! .returning(|| MockA::default()); +//! let mut mock0 = MockA::build(); +//! mock0.expect_bar().return_const(4); +//! mock0.bar(); +//! mock0.checkpoint(); // Does not checkpoint the build method +//! let mock1 = MockA::build(); +//! # } +//! ``` +//! +//! One more thing: Mockall normally creates a zero-argument `new` method for +//! every mock struct. But it *won't* do that when mocking a struct that +//! already has a method named `new`. The `default` method will still be +//! present. +//! +//! ## Modules +//! +//! In addition to mocking types, Mockall can also derive mocks for +//! entire modules of Rust functions. Mockall will generate a new module named +//! "mock_xxx", if "xxx" is the original module's name. You can also use +//! `#[double]` to selectively import the mock module. +//! +//! Be careful! Module functions are static and so have the same caveats as +//! [static methods](#static-methods) described above. +//! +//! ``` +//! # use mockall::*; +//! # use mockall_double::*; +//! mod outer { +//! use mockall::automock; +//! #[automock()] +//! pub(super) mod inner { +//! pub fn bar(x: u32) -> i64 { +//! // ... +//! # 4 +//! } +//! } +//! } +//! +//! #[double] +//! use outer::inner; +//! +//! #[cfg(test)] +//! mod t { +//! use super::*; +//! +//! #[test] +//! fn test_foo_bar() { +//! let ctx = inner::bar_context(); +//! ctx.expect() +//! .returning(|x| i64::from(x + 1)); +//! assert_eq!(5, inner::bar(4)); +//! } +//! } +//! # fn main() {} +//! ``` +//! +//! ### Foreign functions +//! +//! One reason to mock modules is when working with foreign functions. Modules +//! may contain foreign functions, even though structs and traits may not. Like +//! static methods, the expectations are global. +//! +//! ``` +//! # use mockall_double::*; +//! mod outer { +//! # use mockall::*; +//! #[automock] +//! pub mod ffi { +//! extern "C" { +//! pub fn foo(x: u32) -> i64; +//! } +//! } +//! } +//! +//! #[double] +//! use outer::ffi; +//! +//! fn do_stuff() -> i64 { +//! unsafe{ ffi::foo(42) } +//! } +//! +//! #[cfg(test)] +//! mod t { +//! use super::*; +//! +//! #[test] +//! fn test_foo() { +//! let ctx = ffi::foo_context(); +//! ctx.expect() +//! .returning(|x| i64::from(x + 1)); +//! assert_eq!(43, do_stuff()); +//! } +//! } +//! # fn main() {} +//! ``` +//! +//! ## Debug +//! +//! `#[automock]` will automatically generate `Debug` impls when mocking traits +//! and struct impls. `mock!` will too, if you add a `#[derive(Debug)]`, like +//! this: +//! ```no_run +//! # use mockall::*; +//! mock! { +//! #[derive(Debug)] +//! pub Foo {} +//! } +//! # fn main() { +//! # format!("{:?}", &MockFoo::default()); +//! # } +//! ``` +//! +//! ## Async Traits +//! +//! Async traits aren't yet (as of 1.47.0) a part of the Rust language. But +//! they're available from the +//! [`async_trait`](https://docs.rs/async-trait/0.1.38/async_trait/) crate. +//! Mockall is compatible with this crate, with two important limitations: +//! +//! * The `#[automock]` attribute must appear _before_ the `#[async_trait]` +//! attribute. +//! +//! * The `#[async_trait]` macro must be imported with its canonical name. +//! +//! ``` +//! # use async_trait::async_trait; +//! # use mockall::*; +//! // async_trait works with both #[automock] +//! #[automock] +//! #[async_trait] +//! pub trait Foo { +//! async fn foo(&self) -> u32; +//! } +//! // and mock! +//! mock! { +//! pub Bar {} +//! #[async_trait] +//! impl Foo for Bar { +//! async fn foo(&self) -> u32; +//! } +//! } +//! # fn main() {} +//! ``` +//! +//! ## Crate features +//! +//! Mockall has a **nightly** feature. Currently this feature has two +//! effects: +//! +//! * The compiler will produce better error messages. +//! +//! * Expectations for methods whose return type implements `Default` needn't +//! have their return values explicitly set. Instead, they will automatically +//! return the default value. +//! +//! With **nightly** enabled, you can omit the return value like this: +#![cfg_attr(feature = "nightly", doc = "```")] +#![cfg_attr(not(feature = "nightly"), doc = "```should_panic")] +//! # use mockall::*; +//! #[automock] +//! trait Foo { +//! fn foo(&self) -> Vec<u32>; +//! } +//! +//! let mut mock = MockFoo::new(); +//! mock.expect_foo(); +//! assert!(mock.foo().is_empty()); +//! ``` +//! +//! ## Examples +//! +//! For additional examples of Mockall in action, including detailed +//! documentation on the autogenerated methods, see +//! [`examples`](examples). +//! +//! [`Predicate`]: trait.Predicate.html +//! [`Sequence`]: Sequence +//! [`cfg-if`]: https://crates.io/crates/cfg-if +//! [`function`]: predicate/fn.function.html +//! [`mock!`]: macro.mock.html +//! [`predicate`]: predicate/index.html + +#![cfg_attr(feature = "nightly", feature(specialization))] +// Allow the incomplete_feature warning for specialization. We know it's +// incomplete; that's why it's guarded by the "nightly" feature. +#![cfg_attr(feature = "nightly", allow(incomplete_features))] + +#![cfg_attr(feature = "nightly", feature(doc_cfg))] +#![cfg_attr(test, deny(warnings))] +#![warn(missing_docs)] + +use downcast::*; +use std::{ + any, + fmt::{self, Debug, Formatter}, + marker::PhantomData, + ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, + RangeToInclusive}, + sync::{ + Arc, + atomic::{AtomicUsize, Ordering} + }, +}; + +#[doc(hidden)] +pub use downcast::{Any, Downcast}; +#[doc(hidden)] +pub use fragile::Fragile; + +/// For mocking static methods +#[doc(hidden)] +pub use lazy_static::lazy_static; + +pub use predicates::{ + boolean::PredicateBooleanExt, + prelude::{ + Predicate, PredicateBoxExt, PredicateFileContentExt, PredicateStrExt, + predicate + } +}; +#[doc(hidden)] +pub use predicates_tree::CaseTreeExt; + +#[cfg(doc)] +extern crate self as mockall; +#[cfg(doc)] +pub mod examples; + +/// Automatically generate mock types for structs and traits. +/// +/// This is by far the easiest way to use Mockall. It works on almost all +/// traits, and almost all structs that have a single `impl` block. In either +/// case, it will generate a mock struct whose name is the name of the mocked +/// struct/trait prepended with "Mock". For each method of the original, the +/// mock struct will have a method named `expect_whatever` that allows you to +/// set expectations. There will also be one `checkpoint` method that calls +/// [`checkpoint`] for every single mocked method. +/// +/// # Examples +/// +/// The simplest use case is mocking a no-frills trait +/// ``` +/// # use mockall_derive::*; +/// #[automock] +/// pub trait Foo { +/// fn foo(&self, key: i16); +/// } +/// +/// let mock = MockFoo::new(); +/// ``` +/// +/// Mocking a structure: +/// ``` +/// # use mockall_derive::*; +/// struct Foo {} +/// #[automock] +/// impl Foo { +/// fn foo(&self) -> u32 { +/// // ... +/// # unimplemented!() +/// } +/// } +/// ``` +/// +/// You can also mock a trait impl on a struct: +/// ``` +/// # use mockall_derive::*; +/// pub trait Foo { +/// fn foo(&self, key: i16); +/// } +/// struct Bar{} +/// #[automock] +/// impl Foo for Bar { +/// fn foo(&self, key: i16){ +/// // ... +/// # unimplemented!() +/// } +/// } +/// +/// let mock = MockBar::new(); +/// ``` +/// +/// Mocking a trait with associated types requires adding a metaitem to the +/// attribute: +/// ``` +/// # use mockall_derive::*; +/// #[automock(type Item=u32;)] +/// trait Foo { +/// type Item; +/// fn foo(&self) -> Self::Item; +/// } +/// ``` +/// +/// Finally, `#[automock]` can also mock foreign functions. This requires +/// another metaitem to specify the mock module name. +/// +/// ``` +/// # use mockall_derive::*; +/// #[automock(mod mock_ffi;)] +/// extern "C" { +/// pub fn foo() -> u32; +/// } +/// ``` +/// +/// [`checkpoint`]: ../mockall/index.html#checkpoints +/// +/// # Limitations +/// +/// `#[automock]` can't handle everything. There are some cases where +/// you will need to use [`mock`] instead: +/// * Mocking a struct that has multiple `impl` blocks, including +/// structs that implement traits. +/// * Mocking a struct or trait defined in another crate. +/// * Mocking a trait with trait bounds. +/// * If the autogenerated "MockFoo" name isn't acceptable, and you want +/// to choose your own name for the mock structure. +pub use mockall_derive::automock; + +/// Manually mock a structure. +/// +/// Sometimes `automock` can't be used. In those cases you can use `mock!`, +/// which basically involves repeating the struct's or trait's definitions. +/// +/// The format is: +/// +/// * Optional visibility specifier +/// * Real structure name and generics fields +/// * 0 or more methods of the structure, written without bodies, enclosed in a +/// {} block +/// * 0 or more impl blocks implementing traits on the structure, also without +/// bodies. +/// +/// # Examples +/// +/// Mock a trait. This is the simplest use case. +/// ``` +/// # use mockall_derive::mock; +/// trait Foo { +/// fn foo(&self, x: u32); +/// } +/// mock!{ +/// pub MyStruct<T: Clone + 'static> { +/// fn bar(&self) -> u8; +/// } +/// impl<T: Clone + 'static> Foo for MyStruct<T> { +/// fn foo(&self, x: u32); +/// } +/// } +/// # fn main() {} +/// ``` +/// Mocking an unsupported `#[derive(X)]` attribute, e.g. `Clone`, is +/// similar. +/// ``` +/// # use mockall_derive::mock; +/// #[derive(Clone)] +/// struct MyStruct; +/// +/// mock!{ +/// pub MyStruct { +/// fn bar(&self); +/// } +/// impl Clone for MyStruct { +/// fn clone(&self) -> Self; +/// } +/// } +/// # fn main() {} +/// ``` +/// +/// When mocking a generic struct's implementation of a generic trait, use the +/// same namespace for their generic parameters. For example, if you wanted to +/// mock `Rc`, do +/// ``` +/// # use mockall_derive::mock; +/// mock!{ +/// pub Rc<T: 'static> {} +/// impl<T: 'static> AsRef<T> for Rc<T> { +/// fn as_ref(&self) -> &T; +/// } +/// } +/// # fn main() {} +/// ``` +/// *not* +/// ```compile_fail +/// # use mockall_derive::mock; +/// mock!{ +/// pub Rc<Q: 'static> {} +/// impl<T: 'static> AsRef<T> for Rc<T> { +/// fn as_ref(&self) -> &T; +/// } +/// } +/// # fn main() {} +/// ``` +/// Associated types can easily be mocked by specifying a concrete type in the +/// `mock!{}` invocation. +/// ``` +/// # use mockall_derive::mock; +/// mock!{ +/// MyIter {} +/// impl Iterator for MyIter { +/// type Item=u32; +/// +/// fn next(&mut self) -> Option<<Self as Iterator>::Item>; +/// } +/// } +/// # fn main() {} +/// ``` +pub use mockall_derive::mock; + +#[doc(hidden)] +pub trait AnyExpectations : Any + Send + Sync {} +downcast!(dyn AnyExpectations); + +#[doc(hidden)] +pub trait ReturnDefault<O> { + fn maybe_return_default() -> Option<O>; + fn return_default() -> Result<O, &'static str>; +} + +#[derive(Default)] +#[doc(hidden)] +pub struct DefaultReturner<O>(PhantomData<O>); + +::cfg_if::cfg_if! { + if #[cfg(feature = "nightly")] { + impl<O> ReturnDefault<O> for DefaultReturner<O> { + default fn maybe_return_default() -> Option<O> { + None + } + + default fn return_default() -> Result<O, &'static str> { + Err("Can only return default values for types that impl std::Default") + } + } + + impl<O: Default> ReturnDefault<O> for DefaultReturner<O> { + fn maybe_return_default() -> Option<O> { + Some(O::default()) + } + + fn return_default() -> Result<O, &'static str> { + Ok(O::default()) + } + } + } else { + impl<O> ReturnDefault<O> for DefaultReturner<O> { + fn maybe_return_default() -> Option<O> { + None + } + + fn return_default() -> Result<O, &'static str> { + Err("Returning default values requires the \"nightly\" feature") + } + } + } +} + +#[doc(hidden)] +pub struct MaybeDebugger<'a, T>(pub &'a T); +::cfg_if::cfg_if! { + if #[cfg(feature = "nightly")] { + impl<'a, T> Debug for MaybeDebugger<'a, T> { + default fn fmt(&self, f: &mut Formatter<'_>) + -> Result<(), fmt::Error> + { + write!(f, "?") + } + } + impl<'a, T: Debug> Debug for MaybeDebugger<'a, T> { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { + self.0.fmt(f) + } + } + } else { + impl<'a, T> Debug for MaybeDebugger<'a, T> { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "?") + } + } + } +} + +// Though it's not entirely correct, we treat usize::max_value() as +// approximately infinity. +#[derive(Debug)] +#[doc(hidden)] +pub struct TimesRange(Range<usize>); + +impl Default for TimesRange { + fn default() -> TimesRange { + // By default, allow any number of calls + TimesRange(0..usize::max_value()) + } +} + +impl From<usize> for TimesRange { + fn from(n: usize) -> TimesRange { + TimesRange(n..(n+1)) + } +} + +impl From<Range<usize>> for TimesRange { + fn from(r: Range<usize>) -> TimesRange { + assert!(r.end > r.start, "Backwards range"); + TimesRange(r) + } +} + +impl From<RangeFrom<usize>> for TimesRange { + fn from(r: RangeFrom<usize>) -> TimesRange { + TimesRange(r.start..usize::max_value()) + } +} + +impl From<RangeFull> for TimesRange { + fn from(_: RangeFull) -> TimesRange { + TimesRange(0..usize::max_value()) + } +} + +impl From<RangeInclusive<usize>> for TimesRange { + fn from(r: RangeInclusive<usize>) -> TimesRange { + assert!(r.end() >= r.start(), "Backwards range"); + TimesRange(*r.start()..*r.end() + 1) + } +} + +impl From<RangeTo<usize>> for TimesRange { + fn from(r: RangeTo<usize>) -> TimesRange { + TimesRange(0..r.end) + } +} + +impl From<RangeToInclusive<usize>> for TimesRange { + fn from(r: RangeToInclusive<usize>) -> TimesRange { + TimesRange(0..r.end + 1) + } +} + +#[derive(PartialEq)] +#[doc(hidden)] +pub enum ExpectedCalls { + Satisfied, + TooMany, + TooFew, +} + +#[derive(Debug, Default)] +#[doc(hidden)] +pub struct Times{ + /// How many times has the expectation already been called? + count: AtomicUsize, + range: TimesRange +} + +#[doc(hidden)] +impl Times { + pub fn call(&self) -> Result<(), String> { + let count = self.count.fetch_add(1, Ordering::Relaxed) + 1; + if count >= self.range.0.end { + if self.range.0.end == 1 { + Err("should not have been called".to_owned()) + } else { + Err(format!( + "called {} times which is more than the expected {}", + count, + self.range.0.end - 1 + )) + } + } else { + Ok(()) + } + } + + pub fn any(&mut self) { + self.range.0 = 0..usize::max_value(); + } + + /// Return how many times this expectation has been called + pub fn count(&self) -> usize { + self.count.load(Ordering::Relaxed) + } + + /// Has this expectation already been called the maximum allowed number of + /// times? + pub fn is_done(&self) -> bool { + self.count.load(Ordering::Relaxed) >= self.range.0.end - 1 + } + + /// Is it required that this expectation be called an exact number of times, + /// or may it be satisfied by a range of call counts? + pub fn is_exact(&self) -> bool { + (self.range.0.end - self.range.0.start) == 1 + } + + /// Has this expectation already been called the expected number of times? + /// If not, was it too many or too few? + pub fn is_satisfied(&self) -> ExpectedCalls { + let satisfied_lower_bound = self.count.load(Ordering::Relaxed) >= self.range.0.start; + let satisfied_upper_bound = self.count.load(Ordering::Relaxed) < self.range.0.end; + if satisfied_lower_bound && satisfied_upper_bound { + ExpectedCalls::Satisfied + } else if satisfied_lower_bound { + ExpectedCalls::TooMany + } else { + ExpectedCalls::TooFew + } + } + + /// The maximum number of times that this expectation must be called + pub fn maximum(&self) -> usize { + self.range.0.end - 1 + } + + /// The minimum number of times that this expectation must be called + pub fn minimum(&self) -> usize { + self.range.0.start + } + + // https://github.com/rust-lang/rust-clippy/issues/3307 + #[allow(clippy::range_plus_one)] + pub fn n(&mut self, n: usize) { + self.range.0 = n..(n+1); + } + + pub fn never(&mut self) { + self.range.0 = 0..1; + } + + pub fn range(&mut self, range: Range<usize>) { + assert!(range.end > range.start, "Backwards range"); + self.range.0 = range; + } + + pub fn times<T: Into<TimesRange>>(&mut self, t: T) { + self.range = t.into(); + } +} + +/// Non-generic keys to `GenericExpectation` internal storage +#[doc(hidden)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct Key(any::TypeId); + +#[doc(hidden)] +impl Key { + pub fn new<T: 'static + ?Sized>() -> Self { + Key(any::TypeId::of::<T>()) + } +} + +#[doc(hidden)] +pub struct SeqHandle { + inner: Arc<SeqInner>, + seq: usize +} + +impl SeqHandle { + /// Tell the Sequence that this expectation has been fully satisfied + pub fn satisfy(&self) { + self.inner.satisfy(self.seq); + } + + /// Verify that this handle was called in the correct order + pub fn verify(&self, desc: &str) { + self.inner.verify(self.seq, desc); + } +} + +#[derive(Default)] +struct SeqInner { + satisfaction_level: AtomicUsize, +} + +impl SeqInner { + /// Record the call identified by `seq` as fully satisfied. + fn satisfy(&self, seq: usize) { + let old_sl = self.satisfaction_level.fetch_add(1, Ordering::Relaxed); + assert_eq!(old_sl, seq, "Method sequence violation. Was an already-satisfied method called another time?"); + } + + /// Verify that the call identified by `seq` was called in the correct order + fn verify(&self, seq: usize, desc: &str) { + assert_eq!(seq, self.satisfaction_level.load(Ordering::Relaxed), + "{}: Method sequence violation", desc) + } +} + +/// Used to enforce that mock calls must happen in the sequence specified. +/// +/// Each expectation must expect to be called a fixed number of times. Once +/// satisfied, the next expectation in the sequence will expect to be called. +/// +/// # Examples +/// ``` +/// # use mockall::*; +/// #[automock] +/// trait Foo { +/// fn foo(&self); +/// fn bar(&self) -> u32; +/// } +/// let mut seq = Sequence::new(); +/// +/// let mut mock0 = MockFoo::new(); +/// let mut mock1 = MockFoo::new(); +/// +/// mock0.expect_foo() +/// .times(1) +/// .returning(|| ()) +/// .in_sequence(&mut seq); +/// +/// mock1.expect_bar() +/// .times(1) +/// .returning(|| 42) +/// .in_sequence(&mut seq); +/// +/// mock0.foo(); +/// mock1.bar(); +/// ``` +/// +/// It is an error to add an expectation to a `Sequence` if its call count is +/// unspecified. +/// ```should_panic(expected = "with an exact call count") +/// # use mockall::*; +/// #[automock] +/// trait Foo { +/// fn foo(&self); +/// } +/// let mut seq = Sequence::new(); +/// +/// let mut mock = MockFoo::new(); +/// mock.expect_foo() +/// .returning(|| ()) +/// .in_sequence(&mut seq); // panics! +/// ``` +#[derive(Default)] +pub struct Sequence { + inner: Arc<SeqInner>, + next_seq: usize, +} + +impl Sequence { + /// Create a new empty [`Sequence`] + pub fn new() -> Self { + Self::default() + } + + /// Not for public consumption, but it must be public so the generated code + /// can call it. + #[doc(hidden)] + pub fn next_handle(&mut self) -> SeqHandle { + let handle = SeqHandle{inner: self.inner.clone(), seq: self.next_seq}; + self.next_seq += 1; + handle + } +} |