#![cfg(feature = "db")]
use autumn_web::model;
use autumn_web::prelude::*;
use autumn_web::reexports::diesel_async::AsyncPgConnection;
use autumn_web::{Lifecycle, lifecycle};
use serde::{Deserialize, Serialize};
#[lifecycle(
initial = Draft,
terminal(Archived),
transitions(
Draft -> Published,
Published -> Archived,
)
)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OrderState {
Draft,
Published,
Archived,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct EffectArgs {
idempotency_key: String,
}
#[job(name = "lifecycle_effects_announce_publish")]
#[allow(clippy::unused_async)] async fn announce_publish(_state: AppState, _args: EffectArgs) -> AutumnResult<()> {
Ok(())
}
diesel::table! {
lifecycle_effects_articles (id) {
id -> BigInt,
status -> Text,
}
}
#[model(table = "lifecycle_effects_articles")]
pub struct Article {
#[id]
pub id: i64,
#[state_machine(lifecycle = OrderState, effects(
// After-commit enqueue on this edge.
Draft -> Published: on_commit = AnnouncePublishJob,
// Sync in-transaction handler on this edge.
Published -> Archived: on = "record_archive",
))]
pub status: String,
}
impl Article {
#[allow(clippy::unused_async)] async fn record_archive(&self, _conn: &mut AsyncPgConnection) -> AutumnResult<()> {
Ok(())
}
}
fn article(status: &str) -> Article {
Article {
id: 7,
status: status.to_string(),
}
}
#[test]
fn pure_validator_still_governs_lifecycle_edges() {
assert!(article("Draft").can_transition_status_to("Published"));
assert!(article("Published").can_transition_status_to("Archived"));
assert!(!article("Draft").can_transition_status_to("Archived"));
assert!(!article("Archived").can_transition_status_to("Draft"));
assert_eq!(
article("Draft")
.transition_status_to("Published")
.expect("declared edge"),
"Published"
);
assert!(article("Draft").transition_status_to("Archived").is_err());
assert_eq!(
Article::__AUTUMN_SM_STATUS_TRANSITIONS,
<OrderState as Lifecycle>::STATE_MACHINE_TRANSITIONS
);
}
#[allow(dead_code)]
async fn _assert_on_conn_signature(
article: &Article,
conn: &mut AsyncPgConnection,
) -> AutumnResult<String> {
article
.transition_status_to_on_conn(conn, "Published")
.await
}