[][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.


use topo::{call_in_slot, CallId};

let get_name_id = |name, value| {
    call_in_slot(name, || {
        println!("{}", value);

// 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);

        // 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());