use crate::{Actor, ActorBehavior, Message, Port};
use anyhow::{Error, Result};
use reflow_actor::{message::EncodableValue, ActorContext};
use reflow_actor_macro::actor;
use serde_json::json;
use std::collections::HashMap;
#[actor(
LoopActor,
inports::<100>(collection, initial_value),
outports::<50>(item, completed),
state(MemoryState)
)]
pub async fn loop_actor(context: ActorContext) -> Result<HashMap<String, Message>, Error> {
let payload = context.get_payload();
if let Some(Message::Array(collection)) = payload.get("collection") {
if collection.is_empty() {
return Ok([("completed".to_string(), Message::Boolean(true))].into());
}
let outport_tx = context.get_outports().0;
for i in 0..collection.len().saturating_sub(1) {
let item = &collection[i];
let mut out = HashMap::new();
out.insert(
"item".to_string(),
Message::object(EncodableValue::from(json!({
"value": serde_json::to_value(item)?,
"index": i
}))),
);
let _ = outport_tx.send(out);
}
let last_idx = collection.len() - 1;
let last_item = &collection[last_idx];
let mut result = HashMap::new();
result.insert(
"item".to_string(),
Message::object(EncodableValue::from(json!({
"value": serde_json::to_value(last_item)?,
"index": last_idx
}))),
);
Ok(result)
} else {
Ok([("completed".to_string(), Message::Boolean(true))].into())
}
}