use serde::{Deserialize, Serialize};
#[cfg(feature = "json-schema")]
use schemars::JsonSchema;
#[derive(Debug, Clone, Deserialize, Serialize)]
#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
#[serde(untagged)]
pub enum ReplayItem<A> {
#[cfg_attr(
feature = "json-schema",
schemars(description = "Pause until action matching pattern (supports * glob)")
)]
AwaitOne {
_await: String,
},
#[cfg_attr(
feature = "json-schema",
schemars(description = "Pause until any action matching one of the patterns")
)]
AwaitAny {
_await_any: Vec<String>,
},
Action(A),
}
impl<A> ReplayItem<A> {
pub fn is_await(&self) -> bool {
matches!(
self,
ReplayItem::AwaitOne { .. } | ReplayItem::AwaitAny { .. }
)
}
pub fn into_action(self) -> Option<A> {
match self {
ReplayItem::Action(a) => Some(a),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
enum TestAction {
Fetch,
DidLoad(String),
Select(usize),
}
#[test]
fn test_deserialize_action() {
let json = r#""Fetch""#;
let item: ReplayItem<TestAction> = serde_json::from_str(json).unwrap();
assert!(matches!(item, ReplayItem::Action(TestAction::Fetch)));
}
#[test]
fn test_deserialize_action_with_data() {
let json = r#"{"DidLoad": "hello"}"#;
let item: ReplayItem<TestAction> = serde_json::from_str(json).unwrap();
assert!(matches!(
item,
ReplayItem::Action(TestAction::DidLoad(s)) if s == "hello"
));
}
#[test]
fn test_deserialize_await_one() {
let json = r#"{"_await": "DidLoad"}"#;
let item: ReplayItem<TestAction> = serde_json::from_str(json).unwrap();
assert!(matches!(
item,
ReplayItem::AwaitOne { _await } if _await == "DidLoad"
));
}
#[test]
fn test_deserialize_await_any() {
let json = r#"{"_await_any": ["DidLoad", "DidError"]}"#;
let item: ReplayItem<TestAction> = serde_json::from_str(json).unwrap();
match item {
ReplayItem::AwaitAny { _await_any } => {
assert_eq!(_await_any, vec!["DidLoad", "DidError"]);
}
_ => panic!("expected AwaitAny"),
}
}
#[test]
fn test_deserialize_mixed_array() {
let json = r#"[
"Fetch",
{"_await": "*DidLoad"},
{"Select": 0}
]"#;
let items: Vec<ReplayItem<TestAction>> = serde_json::from_str(json).unwrap();
assert_eq!(items.len(), 3);
assert!(matches!(items[0], ReplayItem::Action(TestAction::Fetch)));
assert!(matches!(items[1], ReplayItem::AwaitOne { .. }));
assert!(matches!(
items[2],
ReplayItem::Action(TestAction::Select(0))
));
}
#[test]
fn test_is_await() {
let action: ReplayItem<TestAction> = ReplayItem::Action(TestAction::Fetch);
let await_one: ReplayItem<TestAction> = ReplayItem::AwaitOne {
_await: "test".into(),
};
let await_any: ReplayItem<TestAction> = ReplayItem::AwaitAny {
_await_any: vec!["a".into()],
};
assert!(!action.is_await());
assert!(await_one.is_await());
assert!(await_any.is_await());
}
}