[−][src]Function topo::call_in_slot
pub fn call_in_slot<F, Q: ?Sized, R, S>(slot: &Q, op: F) -> R where
F: FnOnce() -> R,
Q: Eq + Hash + ToOwned<Owned = S>,
S: Borrow<Q> + Eq + Hash + Send + 'static,
Calls the provided function as a child of CallId::current
, using slot
as an input for the new CallId
.
Because this overrides call
's default slot of call count, it is
possible for the same CallId
to be issued multiple times during a
single parent scope.
Examples
use topo::{call_in_slot, CallId}; let get_name_id = |name, value| { call_in_slot(name, || { println!("{}", value); CallId::current() }) }; // reusing the same slot will get the same CallId let bob = get_name_id("bob", "hello"); let bob_again = get_name_id("bob", "hello"); assert_eq!(bob, bob_again); // the same name in a nested call returns a *new* CallId let bob_nested = topo::call(|| get_name_id("bob", "hello")); assert_ne!(bob, bob_nested); // different names produce different slots let alice_hello = get_name_id("alice", "hello"); assert_ne!(bob, alice_hello); // changing non-slot arguments doesn't affect the CallId produced let alice_goodbye = get_name_id("alice", "goodbye"); assert_eq!(alice_hello, alice_goodbye);
Note that while call
uses call_in_slot
internally, there is no way to
manually "reuse" a call count slot with this function.
use topo::{call, call_in_slot, CallId}; let get_lists_of_ids = || { topo::call(|| { let (mut counted_ids, mut slotted_ids) = (vec![], vec![]); for i in 0..3 { // (we're cheating here because we know that call() uses a u32) let slotted = call_in_slot(&(i as u32), CallId::current); let counted = call(CallId::current); if i > 0 { assert_ne!(slotted_ids[i - 1], slotted); assert_ne!(counted_ids[i - 1], counted); } slotted_ids.push(slotted); counted_ids.push(counted); } // these should *not* be the same despite emulating the call count assert_ne!(&counted_ids, &slotted_ids); (counted_ids, slotted_ids) }) }; assert_eq!(get_lists_of_ids(), get_lists_of_ids());