ops_rs/trigger/predicates/
inline.rs1use 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
32impl 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 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}