1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use std::future::Future;
use crate::{
step::{Run, RunAsync, Step},
story::{RunStory, RunStoryAsync, StoryContext},
};
/// A trait for running a story.
pub trait StoryRunner<E> {
/// Called when the root or a nested story starts.
fn start_story(&mut self, story: impl StoryContext) -> Result<(), E>;
/// Called when the root or a nested story ends.
fn end_story(&mut self, story: impl StoryContext) -> Result<(), E>;
/// Executes a step.
/// If you call `step.run_with_runner(env, self)`, the runner will be passed to the nested story if it exists.
fn run_step<T, S>(&mut self, step: T, state: &mut S) -> Result<(), E>
where
T: Step + Run<S, E>;
/// Executes a nested story referenced by a parent step.
/// You can run a nested story step by step with the `Run` trait or all at once with the `RunStory` trait.
/// If you call those methods with `_with_runner` variants with `self`, the runner will be passed to the nested story.
///
/// # Example
/// ```rust,ignore
/// fn run_nested_story<S, Env>(
/// &mut self,
/// _step: impl narrative::step::Step,
/// nested_story: S,
/// env: &mut Env,
/// ) -> Result<(), E>
/// where
/// S::Step: narrative::step::Run<Env, E>,
/// S: narrative::story::StoryContext + narrative::story::RunStory<S, Env, E>,
/// {
/// if self.run_nested_story_step_by_step {
/// for step in nested_story.steps() {
/// step.run_with_runner(env, self)?;
/// }
/// } else {
/// nested_story.run_story_with_runner(env, self)
/// }
/// }
/// ```
fn run_nested_story<S, Env>(
&mut self,
step: impl Step,
nested_story: S,
env: &mut Env,
) -> Result<(), E>
where
S::Step: Run<Env, E>,
S: StoryContext + RunStory<S, Env, E>;
}
/// A trait for running a story asynchronously.
pub trait AsyncStoryRunner<E> {
/// Called when the root or a nested story starts.
fn start_story(&mut self, story: impl StoryContext) -> Result<(), E>;
/// Called when the root or a nested story ends.
fn end_story(&mut self, story: impl StoryContext) -> Result<(), E>;
/// Executes a step asynchronously.
/// If you call `step.run_with_runner_async(env, self)`, the runner will be passed to the nested story if it exists.
fn run_step_async<T, Env>(
&mut self,
step: T,
state: &mut Env,
) -> impl Future<Output = Result<(), E>> + Send
where
T: Step + RunAsync<Env, E> + Send + Sync,
Env: Send;
/// Executes a nested story referenced by a parent step asynchronously.
/// See [StoryRunner::run_nested_story] for more details.
fn run_nested_story_async<S, Env>(
&mut self,
step: impl Step + Send,
nested_story: S,
env: &mut Env,
) -> impl Future<Output = Result<(), E>> + Send
where
S: StoryContext + RunStoryAsync<S, Env, E> + Send + Sync,
Env: Send,
S::Step: RunAsync<Env, E> + Send + Sync;
}
/// The default story runner that executes steps sequentially without extra logic.
pub struct DefaultStoryRunner;
impl<E> StoryRunner<E> for DefaultStoryRunner {
#[inline]
fn start_story(&mut self, _story: impl StoryContext) -> Result<(), E> {
Ok(())
}
#[inline]
fn end_story(&mut self, _story: impl StoryContext) -> Result<(), E> {
Ok(())
}
#[inline]
fn run_step<T, S>(&mut self, step: T, state: &mut S) -> Result<(), E>
where
T: Step + Run<S, E>,
{
step.run(state)
}
#[inline]
fn run_nested_story<NestedCtx: StoryContext + RunStory<NestedCtx, NestedImpl, E>, NestedImpl>(
&mut self,
_parent_step: impl Step,
nested_context: NestedCtx,
nested_impl: &mut NestedImpl,
) -> Result<(), E>
where
NestedCtx::Step: Run<NestedImpl, E>,
{
nested_context.run_story(nested_impl)
}
}
impl<E> AsyncStoryRunner<E> for DefaultStoryRunner {
#[inline]
fn start_story(&mut self, _story: impl StoryContext) -> Result<(), E> {
Ok(())
}
#[inline]
fn end_story(&mut self, _story: impl StoryContext) -> Result<(), E> {
Ok(())
}
#[inline]
async fn run_step_async<T, Env>(&mut self, step: T, state: &mut Env) -> Result<(), E>
where
T: Step + RunAsync<Env, E> + Send + Sync,
Env: Send,
{
step.run_async(state).await
}
#[inline]
async fn run_nested_story_async<S, Env>(
&mut self,
_step: impl Step + Send,
nested_story: S,
env: &mut Env,
) -> Result<(), E>
where
S: StoryContext + RunStoryAsync<S, Env, E> + Send + Sync,
Env: Send,
S::Step: RunAsync<Env, E> + Send + Sync,
{
nested_story.run_story_async(env).await
}
}