npc_engine_utils/
option_state_diff.rs

1/*
2 *  SPDX-License-Identifier: Apache-2.0 OR MIT
3 *  © 2020-2022 ETH Zurich and other contributors, see AUTHORS.txt for details
4 */
5
6use npc_engine_core::{Domain, StateDiffRef, StateDiffRefMut};
7use std::hash::Hash;
8
9/// In case your domain has a [Diff](Domain::Diff) that is an [Option]
10/// of its [State](Domain::State),
11/// provides helper functions to retrieve the state in your [tasks](npc_engine_core::Task).
12///
13/// The functions [get_cur_state](Self::get_cur_state) and [get_cur_state_mut](Self::get_cur_state_mut)
14/// are available when read-only, respectively read-write, access is required.
15/// In that case, just use the trait in your task files: `use npc_engine_utils::OptionDiffDomain;`.
16pub trait OptionDiffDomain {
17    type Domain: Domain<State = Self::State, Diff = Option<Self::State>>;
18    type State: Clone;
19    /// Returns either the `diff` if it is not `None`, or the `initial_state`.
20    fn get_cur_state(
21        state_diff: StateDiffRef<Self::Domain>,
22    ) -> &<<Self as OptionDiffDomain>::Domain as Domain>::State {
23        if let Some(diff) = state_diff.diff {
24            diff
25        } else {
26            state_diff.initial_state
27        }
28    }
29    /// Returns either the `diff` if it is not `None`, or copies the `initial_state` into the `diff` and returns it.
30    fn get_cur_state_mut(
31        state_diff: StateDiffRefMut<Self::Domain>,
32    ) -> &mut <<Self as OptionDiffDomain>::Domain as Domain>::State {
33        if let Some(diff) = state_diff.diff {
34            diff
35        } else {
36            let diff = state_diff.initial_state.clone();
37            *state_diff.diff = Some(diff);
38            &mut *state_diff.diff.as_mut().unwrap()
39        }
40    }
41}
42
43impl<
44        S: std::fmt::Debug + Sized + Clone + Hash + Eq,
45        DA: std::fmt::Debug + Default,
46        D: Domain<State = S, Diff = Option<S>, DisplayAction = DA>,
47    > OptionDiffDomain for D
48{
49    type Domain = D;
50    type State = <D as Domain>::State;
51}