use std::sync::Arc;
use crate::Rocket;
use crate::plugin::Plugin;
pub struct FlowCtrl {
cursor: usize,
plugins: Vec<Arc<dyn Plugin>>,
is_ceased: bool,
}
impl std::fmt::Debug for FlowCtrl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FlowCtrl")
.field("cursor", &self.cursor)
.field("plugins_count", &self.plugins.len())
.field("is_ceased", &self.is_ceased)
.finish()
}
}
impl FlowCtrl {
#[must_use]
pub fn new(plugins: Vec<Arc<dyn Plugin>>) -> Self {
Self {
cursor: 0,
plugins,
is_ceased: false,
}
}
pub async fn call_next(&mut self, rocket: &mut Rocket) -> crate::Result<()> {
if self.is_ceased || !self.has_next() {
return Ok(());
}
let plugin = self.plugins[self.cursor].clone();
self.cursor += 1;
plugin.assembly(rocket, Next { ctrl: self }).await
}
#[must_use]
pub fn has_next(&self) -> bool {
self.cursor < self.plugins.len()
}
pub fn skip_rest(&mut self) {
self.cursor = self.plugins.len();
self.is_ceased = true;
}
pub fn cease(&mut self) {
self.is_ceased = true;
self.skip_rest();
}
#[must_use]
pub fn is_ceased(&self) -> bool {
self.is_ceased
}
}
pub struct Next<'a> {
pub(crate) ctrl: &'a mut FlowCtrl,
}
impl Next<'_> {
pub async fn call(self, rocket: &mut Rocket) -> crate::Result<()> {
self.ctrl.call_next(rocket).await
}
}