use ops::prelude::*;
use ops::{batch, repeat, repeat_until};
#[derive(Debug)]
struct StartTransactionOp;
#[async_trait]
impl Op<()> for StartTransactionOp {
async fn perform(&self, _dry: &mut DryContext, _wet: &mut WetContext) -> OpResult<()> {
println!("Transaction started");
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("StartTransactionOp").build()
}
}
#[derive(Debug)]
struct LoadContentOp {
prefix: String,
}
impl LoadContentOp {
fn new(prefix: String) -> Self {
Self { prefix }
}
}
#[async_trait]
impl Op<()> for LoadContentOp {
async fn perform(&self, dry: &mut DryContext, _wet: &mut WetContext) -> OpResult<()> {
let iteration = dry.get::<usize>(&self.prefix).unwrap_or(0);
println!("Loading content for iteration {}", iteration);
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("LoadContentOp").build()
}
}
#[derive(Debug)]
struct InsertDataOp {
config: String,
}
impl InsertDataOp {
fn with(config: impl Into<String>) -> Self {
Self {
config: config.into(),
}
}
}
#[async_trait]
impl Op<()> for InsertDataOp {
async fn perform(&self, _dry: &mut DryContext, _wet: &mut WetContext) -> OpResult<()> {
println!("Inserting data with config: {}", self.config);
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("InsertDataOp").build()
}
}
#[derive(Debug)]
struct MakeDecisionOp;
#[async_trait]
impl Op<()> for MakeDecisionOp {
async fn perform(&self, _dry: &mut DryContext, _wet: &mut WetContext) -> OpResult<()> {
println!("Making Make Decision");
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("MakeDecisionOp").build()
}
}
#[derive(Debug)]
struct ReactToContentSelectionResponse;
#[async_trait]
impl Op<()> for ReactToContentSelectionResponse {
async fn perform(&self, _dry: &mut DryContext, _wet: &mut WetContext) -> OpResult<()> {
println!("Reacting to content selection response");
Ok(())
}
fn metadata(&self) -> OpMetadata {
OpMetadata::builder("ReactToContentSelectionResponse").build()
}
}
batch! {
ContentSelectionOp<()> -> unit = [
LoadContentOp::new("cso".to_string()),
InsertDataOp::with("default_config"),
MakeDecisionOp,
ReactToContentSelectionResponse
]
}
repeat! {
ContentSelectionLoopOp<()> -> unit = {
counter: "cso",
limit: "cso_limit",
ops: [
LoadContentOp::new("cso".to_string()),
InsertDataOp::with("default_config"),
MakeDecisionOp,
ReactToContentSelectionResponse
]
}
}
repeat_until! {
ContentSelectionWhileOp<()> -> unit = {
counter: "cso",
condition: "has_more_content",
max_iterations: 100,
ops: [
LoadContentOp::new("cso".to_string()),
InsertDataOp::with("default_config"),
MakeDecisionOp,
ReactToContentSelectionResponse
]
}
}
batch! {
CloseReadOpBatch<()> -> unit = [
StartTransactionOp,
ContentSelectionOp::new(), ContentSelectionLoopOp::new(), ContentSelectionWhileOp::new() ]
}
batch! {
FlexiblePipeline<()> = [
StartTransactionOp,
ContentSelectionOp::new()
]
}
batch! {
FlexiblePipelineUnit<()> -> unit = [
StartTransactionOp,
ContentSelectionOp::new()
]
}
repeat! {
ContentSelectionLastResult<()> -> last = {
counter: "cso",
limit: "cso_limit",
ops: [
LoadContentOp::new("cso".to_string()),
MakeDecisionOp
]
}
}
batch! {
FullyComposablePipeline<()> -> unit = [
StartTransactionOp,
ContentSelectionOp::new(),
ContentSelectionLoopOp::new(),
ContentSelectionWhileOp::new(),
ContentSelectionLastResult::new()
]
}
#[tokio::main]
async fn main() -> OpResult<()> {
let mut dry = DryContext::new();
let mut wet = WetContext::new();
dry.insert("cso_limit", 3_usize);
dry.insert("has_more_content", true);
println!("=== Content Selection with Sequential Execution ===");
let content_op = ContentSelectionOp::new();
let result = content_op.perform(&mut dry, &mut wet).await?;
println!("Sequential content selection result: {:?}", result);
println!("\n=== Content Selection with Loop ===");
let loop_op = ContentSelectionLoopOp::new();
let result = loop_op.perform(&mut dry, &mut wet).await?;
println!("Loop content selection result: {:?}", result);
println!("\n=== Content Selection with While Loop ===");
dry.insert("has_more_content", true);
let while_op = ContentSelectionWhileOp::new();
let result = while_op.perform(&mut dry, &mut wet).await?;
println!("While loop content selection result: {:?}", result);
println!("\n=== Full Extraction Pipeline ===");
let extraction_pipeline = CloseReadOpBatch::new();
let result = extraction_pipeline.perform(&mut dry, &mut wet).await?;
println!("Full extraction pipeline result: {:?}", result);
println!("\n=== Fully Composable Pipeline ===");
let composable_pipeline = FullyComposablePipeline::new();
let result = composable_pipeline.perform(&mut dry, &mut wet).await?;
println!("Fully composable pipeline result: {:?}", result);
Ok(())
}