use super::Play;
use super::Step;
use super::Story;
use leptos::attr::any_attribute::AnyAttribute;
use leptos::prelude::IntoAnyAttribute;
use leptos::view;
use leptos::web_sys::HtmlElement;
type StepFn<S> = fn(canvas: &HtmlElement, &mut S) -> Result<(), &'static str>;
#[derive(Clone)]
pub struct SimpleStep<S: Story> {
description: &'static str,
step: StepFn<S>,
}
impl<S: Story> SimpleStep<S> {
pub fn new(description: &'static str, step: StepFn<S>) -> Self {
Self { description, step }
}
}
impl<S: Story> Step for SimpleStep<S> {
type Story = S;
fn description(&self) -> &'static str {
self.description
}
fn run(&self, canvas: &HtmlElement, story: &mut Self::Story) -> Result<(), &'static str> {
(self.step)(canvas, story)
}
}
impl<S: Story + 'static> From<SimpleStep<S>> for Box<dyn Step<Story = S>> {
fn from(val: SimpleStep<S>) -> Self {
Box::new(val)
}
}
pub struct SimplePlay<S: Story> {
description: &'static str,
steps: Vec<SimpleStep<S>>,
}
impl<S: Story> SimplePlay<S> {
pub fn next(mut self, name: &'static str, step: StepFn<S>) -> Self {
self.steps.push(SimpleStep::new(name, step));
self
}
}
impl<S: Story + 'static> From<SimplePlay<S>> for Box<dyn Play<Story = S>> {
fn from(value: SimplePlay<S>) -> Self {
Box::new(value)
}
}
impl<S: Story + 'static> Play for SimplePlay<S> {
type Story = S;
fn description(&self) -> &'static str {
self.description
}
fn steps(&self) -> Vec<Box<dyn Step<Story = Self::Story>>> {
self.steps
.iter()
.map(|step| step.clone().into())
.collect::<Vec<_>>()
}
}
pub fn play<S: Story>(name: &'static str) -> SimplePlay<S> {
SimplePlay {
description: name,
steps: Vec::new(),
}
}
pub fn test_id<S: ToString>(test_id: Option<S>) -> AnyAttribute {
if let Some(test_id) = test_id {
(view! {
<{..} data-testid={test_id.to_string()} />
})
.into_any_attr()
} else {
().into_any_attr()
}
}