murf/
misc.rs

1//! The [`misc`](self) crate contains different helper types and traits.
2
3use std::borrow::Borrow;
4use std::cell::RefCell;
5use std::fmt::Display;
6use std::rc::Rc;
7use std::sync::{
8    atomic::{AtomicUsize, Ordering},
9    Arc, Mutex,
10};
11
12/// Helper type that is used to the values a pointer like type is pointing to.
13///
14/// This is mostly used in the [`ReturnPointee`](crate::action::ReturnPointee) type.
15pub trait Pointee<T> {
16    /// Get the value the pointer type is currently pointing at.
17    fn get(&self) -> T;
18}
19
20impl<T> Pointee<T> for Rc<RefCell<T>>
21where
22    T: Clone,
23{
24    fn get(&self) -> T {
25        RefCell::borrow(self).clone()
26    }
27}
28
29impl<T> Pointee<T> for Arc<Mutex<T>>
30where
31    T: Clone,
32{
33    fn get(&self) -> T {
34        self.lock().unwrap().clone()
35    }
36}
37
38/// Implements [`Pointee`] for any type `T` that implements [`Borrow`].
39#[derive(Debug)]
40pub struct Borrowed<T>(T);
41
42impl<T, X> Pointee<T> for Borrowed<X>
43where
44    X: Borrow<T>,
45    T: Clone,
46{
47    fn get(&self) -> T {
48        self.0.borrow().clone()
49    }
50}
51
52/// Implements [`Pointee`] for any pointer type `* const T`.
53#[derive(Debug)]
54pub struct Pointer<T>(pub *const T);
55
56impl<T> Pointee<T> for Pointer<T>
57where
58    T: Clone,
59{
60    fn get(&self) -> T {
61        unsafe { &*self.0 }.clone()
62    }
63}
64
65/// Defines a expectation for a function call on a mocked object.
66pub trait Expectation: Display {
67    /// Returns the type id of the expectation.
68    fn type_id(&self) -> usize;
69
70    /// Returns `true` if this expectation is ready, `false` otherwise.
71    ///
72    /// Ready means that the expectation was executed the expected amount of times.
73    fn is_ready(&self) -> bool;
74
75    /// Mark this expectation as done.
76    ///
77    /// Done means that this expectation has been finished and will not called again.
78    fn set_done(&self);
79
80    /// Get the type signature of the expectation.
81    fn type_signature(&self) -> &'static str;
82}
83
84/// Get the next type id
85pub fn next_type_id() -> usize {
86    NEXT_TYPE_ID.fetch_add(1, Ordering::Relaxed)
87}
88
89static NEXT_TYPE_ID: AtomicUsize = AtomicUsize::new(0);