Skip to main content

card_stack/
priority.rs

1use crate::{
2    EmptyInput, NonEmptyInput,
3    requirements::{RequirementAction, TryNewRequirementActionError},
4};
5
6pub trait GetState<State> {
7    fn state(&self) -> &State;
8}
9
10/// `State`: state of the entire game.
11#[derive(Clone)]
12pub struct Priority<State> {
13    state: State,
14}
15impl<State: std::fmt::Debug> std::fmt::Debug for Priority<State> {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        f.debug_struct("Priority")
18            .field("state", &self.state)
19            .finish()
20    }
21}
22impl<State> Priority<State> {
23    pub fn new(state: State) -> Self {
24        Priority { state }
25    }
26    pub fn state(&self) -> &State {
27        &self.state
28    }
29    pub fn take_state(self) -> State {
30        self.state
31    }
32    pub fn stack<IncitingAction: crate::actions::IncitingActionInfo<State>>(
33        self,
34        inciting_action: IncitingAction,
35    ) -> PriorityStack<State, IncitingAction> {
36        PriorityStack::new(self, inciting_action.into())
37    }
38    pub fn into_state<NewState>(self) -> Priority<NewState>
39    where
40        State: Into<NewState>,
41    {
42        Priority::new(self.state.into())
43    }
44}
45impl<State: GetState<InnerState>, InnerState> GetState<InnerState> for Priority<State> {
46    fn state(&self) -> &InnerState {
47        self.state.state()
48    }
49}
50
51#[derive(Debug)]
52pub struct PriorityMut<Priority> {
53    priority: Priority,
54}
55impl<Priority> PriorityMut<Priority> {
56    pub fn priority(&self) -> &Priority {
57        &self.priority
58    }
59    pub fn priority_mut(&mut self) -> &mut Priority {
60        &mut self.priority
61    }
62    pub fn take_priority(self) -> Priority {
63        self.priority
64    }
65}
66impl<State> PriorityMut<Priority<State>> {
67    #[cfg(not(feature = "internals"))]
68    pub(crate) fn new(priority: Priority<State>) -> Self {
69        PriorityMut { priority }
70    }
71    #[cfg(feature = "internals")]
72    pub fn new(priority: Priority<State>) -> Self {
73        PriorityMut { priority }
74    }
75    pub fn take_state(self) -> State {
76        self.priority.state
77    }
78    pub fn state(&self) -> &State {
79        self.priority.state()
80    }
81    pub fn state_mut(&mut self) -> &mut State {
82        &mut self.priority.state
83    }
84    pub fn stack<IncitingAction: crate::actions::IncitingActionInfo<State>>(
85        self,
86        inciting_action: IncitingAction,
87    ) -> PriorityMut<PriorityStack<State, IncitingAction>> {
88        PriorityMut::<PriorityStack<State, IncitingAction>>::new(
89            self.priority.stack(inciting_action),
90        )
91    }
92    pub fn into_state<NewState>(self) -> PriorityMut<Priority<NewState>>
93    where
94        State: Into<NewState>,
95    {
96        PriorityMut::<Priority<_>>::new(self.priority.into_state())
97    }
98}
99impl<State, IncitingAction: crate::actions::IncitingActionInfo<State>>
100    PriorityMut<PriorityStack<State, IncitingAction>>
101{
102    #[cfg(not(feature = "internals"))]
103    pub(crate) fn new(priority: PriorityStack<State, IncitingAction>) -> Self {
104        PriorityMut { priority }
105    }
106    #[cfg(feature = "internals")]
107    pub fn new(priority: PriorityStack<State, IncitingAction>) -> Self {
108        PriorityMut { priority }
109    }
110    pub fn state_mut(&mut self) -> &mut State {
111        &mut self.priority.priority.state
112    }
113    pub fn stack(mut self, stack_action: impl Into<IncitingAction::Stackable>) -> Self {
114        self.priority = self.priority.stack(stack_action.into());
115        self
116    }
117    pub fn into_state<NewState, NewIncitingAction: crate::actions::IncitingActionInfo<NewState>>(
118        self,
119    ) -> PriorityMut<PriorityStack<NewState, NewIncitingAction>>
120    where
121        State: Into<NewState>,
122        IncitingAction: Into<NewIncitingAction>,
123        <IncitingAction as crate::actions::IncitingActionInfo<State>>::Stackable:
124            Into<<NewIncitingAction as crate::actions::IncitingActionInfo<NewState>>::Stackable>,
125    {
126        PriorityMut::<PriorityStack<_, _>>::new(self.priority.into_state())
127    }
128}
129impl<State: GetState<InnerState>, InnerState> GetState<InnerState> for PriorityMut<State> {
130    fn state(&self) -> &InnerState {
131        self.priority.state()
132    }
133}
134
135pub struct PriorityStack<State, IncitingAction: crate::actions::IncitingActionInfo<State>> {
136    priority: Priority<State>,
137    stack: crate::Stack<State, IncitingAction>,
138}
139impl<State: Clone, IncitingAction: crate::actions::IncitingActionInfo<State> + Clone> Clone
140    for PriorityStack<State, IncitingAction>
141where
142    IncitingAction::Stackable: Clone,
143{
144    fn clone(&self) -> Self {
145        PriorityStack {
146            priority: self.priority.clone(),
147            stack: self.stack.clone(),
148        }
149    }
150}
151impl<OldState, OldIncitingAction: crate::actions::IncitingActionInfo<OldState>>
152    PriorityStack<OldState, OldIncitingAction>
153{
154    pub fn into_state<NewState, NewIncitingAction: crate::actions::IncitingActionInfo<NewState>>(
155        self,
156    ) -> PriorityStack<NewState, NewIncitingAction>
157    where
158        OldState: Into<NewState>,
159        OldIncitingAction: Into<NewIncitingAction>,
160        <OldIncitingAction as crate::actions::IncitingActionInfo<OldState>>::Stackable:
161            Into<<NewIncitingAction as crate::actions::IncitingActionInfo<NewState>>::Stackable>,
162    {
163        PriorityStack {
164            priority: self.priority.into_state(),
165            stack: self.stack.into_state(),
166        }
167    }
168}
169impl<
170    State: std::fmt::Debug,
171    IncitingAction: crate::actions::IncitingActionInfo<State> + std::fmt::Debug,
172> std::fmt::Debug for PriorityStack<State, IncitingAction>
173where
174    IncitingAction::Stackable: std::fmt::Debug,
175{
176    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
177        f.debug_struct("PriorityStack")
178            .field("priority", &self.priority)
179            .field("stack", &self.stack)
180            .finish()
181    }
182}
183
184impl<State, IncitingAction: crate::actions::IncitingActionInfo<State>>
185    PriorityStack<State, IncitingAction>
186{
187    pub(crate) fn new(priority: Priority<State>, inciting_action: IncitingAction) -> Self {
188        PriorityStack {
189            priority,
190            stack: crate::Stack::new(inciting_action),
191        }
192    }
193    #[cfg(feature = "internals")]
194    pub fn from_stack(
195        priority: Priority<State>,
196        stack: crate::Stack<State, IncitingAction>,
197    ) -> Self {
198        PriorityStack { priority, stack }
199    }
200    #[cfg(feature = "internals")]
201    pub fn take_contents(self) -> (State, crate::Stack<State, IncitingAction>) {
202        (self.priority.state, self.stack)
203    }
204    pub fn priority(&self) -> &Priority<State> {
205        &self.priority
206    }
207    pub fn state(&self) -> &State {
208        self.priority.state()
209    }
210    /// Does NOT include the inciting action.
211    pub fn stack_count(&self) -> usize {
212        self.stack.stack.len()
213    }
214    pub fn stack(
215        mut self,
216        stack_action: impl Into<IncitingAction::Stackable>,
217    ) -> PriorityStack<State, IncitingAction> {
218        self.stack.stack(stack_action.into());
219        self
220    }
221}
222impl<
223    State: GetState<InnerState>,
224    InnerState,
225    IncitingAction: crate::actions::IncitingActionInfo<State>,
226> GetState<InnerState> for PriorityStack<State, IncitingAction>
227{
228    fn state(&self) -> &InnerState {
229        self.priority.state.state()
230    }
231}
232
233pub trait Resolver<State, Input, IncitingAction: crate::actions::IncitingAction<State, Input>>:
234    Sized
235{
236    fn resolve_next<
237        R: IncitingResolver<State, Input, IncitingAction> + StackResolver<State, IncitingAction>,
238    >(
239        self,
240        resolver: &mut R,
241    ) -> ResolveStack<Self, R::Resolved, R::HaltStack>;
242}
243impl<State, Input, IncitingAction: crate::actions::IncitingAction<State, Input>>
244    Resolver<State, Input, IncitingAction> for PriorityStack<State, IncitingAction>
245{
246    fn resolve_next<
247        R: IncitingResolver<State, Input, IncitingAction> + StackResolver<State, IncitingAction>,
248    >(
249        mut self,
250        resolver: &mut R,
251    ) -> ResolveStack<Self, R::Resolved, R::HaltStack> {
252        if let Some(action) = self.stack.pop() {
253            match resolver.resolve_stack(
254                PriorityMut::<PriorityStack<State, IncitingAction>>::new(self),
255                action,
256            ) {
257                Resolve::Continue(priority) => ResolveStack::Next(priority),
258                Resolve::Halt(data) => ResolveStack::Halt(data),
259            }
260        } else {
261            let inciting_action = self.stack.take_inciting_action();
262            ResolveStack::Complete(resolver.resolve_inciting(
263                PriorityMut::<Priority<State>>::new(self.priority),
264                inciting_action,
265            ))
266        }
267    }
268}
269pub trait IncitingResolver<
270    State,
271    Input,
272    IncitingAction: crate::actions::IncitingAction<State, Input>,
273>
274{
275    type Resolved;
276    fn resolve_inciting(
277        &mut self,
278        priority: PriorityMut<Priority<State>>,
279        action: IncitingAction,
280    ) -> Self::Resolved;
281}
282impl<
283    State,
284    IncitingAction: crate::actions::IncitingAction<State, (), Requirement = ()>,
285    Resolver: StackResolver<State, IncitingAction>,
286> IncitingResolver<State, (), IncitingAction> for Resolver
287{
288    type Resolved = IncitingAction::Resolved;
289    fn resolve_inciting(
290        &mut self,
291        priority: PriorityMut<Priority<State>>,
292        action: IncitingAction,
293    ) -> Self::Resolved {
294        action.resolve(priority, ())
295    }
296}
297impl<
298    State,
299    Input: NonEmptyInput,
300    IncitingAction: crate::actions::IncitingAction<State, Input>,
301    Resolver: StackResolver<State, IncitingAction>,
302> IncitingResolver<State, Input, IncitingAction> for Resolver
303{
304    type Resolved = Result<
305        RequirementAction<Priority<State>, Input, IncitingAction>,
306        TryNewRequirementActionError<Priority<State>, IncitingAction>,
307    >;
308    fn resolve_inciting(
309        &mut self,
310        priority: PriorityMut<Priority<State>>,
311        action: IncitingAction,
312    ) -> Self::Resolved {
313        RequirementAction::<Priority<State>, Input, IncitingAction>::try_new(
314            priority.take_priority(),
315            action,
316        )
317    }
318}
319pub trait StackResolver<State, IncitingAction: crate::actions::IncitingActionInfo<State>> {
320    type HaltStack;
321    fn resolve_stack(
322        &mut self,
323        priority: PriorityMut<PriorityStack<State, IncitingAction>>,
324        action: IncitingAction::Stackable,
325    ) -> Resolve<PriorityStack<State, IncitingAction>, Self::HaltStack>;
326}
327pub enum Resolve<Priority, Halt> {
328    Continue(Priority),
329    Halt(Halt),
330}
331impl<State, Break, IncitingAction: crate::actions::IncitingActionInfo<State>>
332    From<PriorityStack<State, IncitingAction>>
333    for Resolve<PriorityStack<State, IncitingAction>, Break>
334{
335    fn from(priority: PriorityStack<State, IncitingAction>) -> Self {
336        Resolve::Continue(priority)
337    }
338}
339pub enum ResolveStack<Priority, Data, Halt> {
340    Next(Priority),
341    Complete(Data),
342    Halt(Halt),
343}
344pub enum ResolveStackFully<Data, Broken> {
345    Complete(Data),
346    Broken(Broken),
347}
348
349#[derive(thiserror::Error)]
350pub struct PriorityError<Priority, Error: std::error::Error + Send + Sync> {
351    pub priority: Priority,
352    #[source]
353    pub error: Error,
354}
355
356impl<State, Error: std::error::Error + Send + Sync> std::fmt::Debug
357    for PriorityError<State, Error>
358{
359    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
360        write!(f, "{:?}", self.error)
361    }
362}