Skip to main content

ConditionBackend

Trait ConditionBackend 

Source
pub trait ConditionBackend:
    Send
    + Sync
    + 'static {
    // Required methods
    fn declaration(&self) -> &ConditionDeclaration;
    fn evaluate(&self, state: &WorkflowState) -> Result<bool, AppError>;
}
Expand description

A caller-owned predicate evaluated against the full immutable workflow state.

App validates declared reads before evaluating the predicate, including reads within composed conditions that would otherwise short-circuit.

§Example

use app_kit::{AppError, workflow::{ConditionBackend, ConditionDeclaration, WorkflowState}};
struct Ready { declaration: ConditionDeclaration }
impl ConditionBackend for Ready {
    fn declaration(&self) -> &ConditionDeclaration { &self.declaration }
    fn evaluate(&self, state: &WorkflowState) -> Result<bool, AppError> {
        let count = state.values().get("count").and_then(serde_json::Value::as_i64)
            .ok_or_else(|| AppError::InvalidInput("count must be an integer".into()))?;
        Ok(count >= 3)
    }
}
let condition = Ready { declaration: ConditionDeclaration {
    key: "ready".into(), revision: "r1".into(), reads: vec!["count".into()],
} };
let state = WorkflowState::new(serde_json::from_str(r#"{"count":3}"#)?)?;
assert!(condition.evaluate(&state)?);

Required Methods§

Source

fn declaration(&self) -> &ConditionDeclaration

Returns the stable declaration for one logical predicate revision.

§Example
use app_kit::{AppError, workflow::{ConditionBackend, ConditionDeclaration, WorkflowState}};
struct Ready { declaration: ConditionDeclaration }
impl ConditionBackend for Ready {
    fn declaration(&self) -> &ConditionDeclaration { &self.declaration }
    fn evaluate(&self, state: &WorkflowState) -> Result<bool, AppError> {
        let count = state.values().get("count").and_then(serde_json::Value::as_i64)
            .ok_or_else(|| AppError::InvalidInput("count must be an integer".into()))?;
        Ok(count >= 3)
    }
}
let condition = Ready { declaration: ConditionDeclaration {
    key: "ready".into(), revision: "r1".into(), reads: vec!["count".into()],
} };
assert_eq!(condition.declaration().key, "ready");
assert_eq!(condition.declaration().reads, ["count"]);
Source

fn evaluate(&self, state: &WorkflowState) -> Result<bool, AppError>

Evaluates the predicate without advancing workflow state or action ordinals.

§Errors

Return an error when evaluation cannot produce a valid boolean. App validates declared reads before calling this method; caller failures stop that routing decision rather than being interpreted as false.

§Example
use app_kit::{AppError, workflow::{ConditionBackend, ConditionDeclaration, WorkflowState}};
struct Ready { declaration: ConditionDeclaration }
impl ConditionBackend for Ready {
    fn declaration(&self) -> &ConditionDeclaration { &self.declaration }
    fn evaluate(&self, state: &WorkflowState) -> Result<bool, AppError> {
        let count = state.values().get("count").and_then(serde_json::Value::as_i64)
            .ok_or_else(|| AppError::InvalidInput("count must be an integer".into()))?;
        Ok(count >= 3)
    }
}
let condition = Ready { declaration: ConditionDeclaration {
    key: "ready".into(), revision: "r1".into(), reads: vec!["count".into()],
} };
let state = WorkflowState::new(serde_json::from_str(r#"{"count":3}"#)?)?;
assert!(condition.evaluate(&state)?);

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§