use std::future::Future;
use std::sync::Arc;
use durable_lambda_core::backend::RealBackend;
use durable_lambda_core::context::DurableContext;
use durable_lambda_core::error::DurableError;
use durable_lambda_core::event::parse_invocation;
use durable_lambda_core::response::wrap_handler_result;
use lambda_runtime::{service_fn, LambdaEvent};
use crate::context::ClosureContext;
pub async fn run<F, Fut>(handler: F) -> Result<(), lambda_runtime::Error>
where
F: Fn(serde_json::Value, ClosureContext) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Result<serde_json::Value, DurableError>> + Send,
{
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let client = aws_sdk_lambda::Client::new(&config);
let backend = Arc::new(RealBackend::new(client));
lambda_runtime::run(service_fn(|event: LambdaEvent<serde_json::Value>| {
let backend = backend.clone();
let handler = &handler;
async move {
let (payload, _lambda_ctx) = event.into_parts();
let invocation = parse_invocation(&payload)
.map_err(Box::<dyn std::error::Error + Send + Sync>::from)?;
let durable_ctx = DurableContext::new(
backend,
invocation.durable_execution_arn,
invocation.checkpoint_token,
invocation.operations,
invocation.next_marker,
)
.await
.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)?;
let closure_ctx = ClosureContext::new(durable_ctx);
let result = handler(invocation.user_event, closure_ctx).await;
wrap_handler_result(result)
}
}))
.await
}