1use crate::{
2 EmptyInput, NonEmptyInput,
3 requirements::{RequirementAction, TryNewRequirementActionError},
4};
5
6pub trait GetState<State> {
7 fn state(&self) -> &State;
8}
9
10#[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 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}