Skip to main content

ops_rs/trigger/predicates/
inline.rs

1use crate::{DryContext, Op, OpMetadata, OpResult, WetContext};
2use async_trait::async_trait;
3use serde_json::json;
4use std::pin::Pin;
5use std::{fmt::Debug, future::Future, sync::Arc};
6
7type AsyncHandler = Arc<
8    dyn Fn(&mut DryContext, &mut WetContext) -> Pin<Box<dyn Future<Output = OpResult<bool>> + Send>>
9        + Send
10        + Sync,
11>;
12
13#[derive(Clone)]
14pub struct InlinePredicateOp {
15    handler: AsyncHandler,
16}
17
18impl InlinePredicateOp {
19    pub fn new<F, Fut>(handler: F) -> Self
20    where
21        F: Fn(&mut DryContext, &mut WetContext) -> Fut + Send + Sync + 'static,
22        Fut: Future<Output = OpResult<bool>> + Send + 'static,
23    {
24        let boxed_handler: AsyncHandler = Arc::new(move |dry, wet| Box::pin(handler(dry, wet)));
25
26        Self {
27            handler: boxed_handler,
28        }
29    }
30}
31
32// Default implementation uses a trivial predicate that always returns true
33impl Default for InlinePredicateOp {
34    fn default() -> Self {
35        Self::new(|_, _| async { Ok(true) })
36    }
37}
38
39impl Debug for InlinePredicateOp {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        f.debug_struct("InlinePredicateOp").finish()
42    }
43}
44
45#[async_trait]
46impl Op<bool> for InlinePredicateOp {
47    async fn perform(&self, dry: &mut DryContext, wet: &mut WetContext) -> OpResult<bool> {
48        // Execute the async handler
49        let decision: bool = (self.handler)(dry, wet).await?;
50
51        Ok(decision)
52    }
53
54    fn metadata(&self) -> OpMetadata {
55        OpMetadata::builder("InlinePredicateOp")
56            .description("Execute custom async handler with access to dry and wet contexts")
57            .input_schema(json!({
58                "type": "object",
59                "properties": {},
60                "description": "No specific input required"
61            }))
62            .output_schema(json!({
63                "type": "boolean",
64                "description": "Result of the decision operation"
65            }))
66            .build()
67    }
68}