use crate::{CallbackRequest, CallbackResponse, PayloadEnvelope, SCHEMA_VERSION};
use super::plan::RoutingPlan;
use super::seams::CallbackInvoker;
pub trait ClientCallback {
type Error;
fn dispatch(
&self,
request: &CallbackRequest,
payloads: &[PayloadEnvelope],
) -> Result<CallbackResponse, Self::Error>;
}
pub struct FnClientCallback<F, E>
where
F: Fn(&CallbackRequest, &[PayloadEnvelope]) -> Result<CallbackResponse, E>,
{
f: F,
_marker: std::marker::PhantomData<E>,
}
impl<F, E> FnClientCallback<F, E>
where
F: Fn(&CallbackRequest, &[PayloadEnvelope]) -> Result<CallbackResponse, E>,
{
pub fn new(f: F) -> Self {
Self {
f,
_marker: std::marker::PhantomData,
}
}
}
impl<F, E> ClientCallback for FnClientCallback<F, E>
where
F: Fn(&CallbackRequest, &[PayloadEnvelope]) -> Result<CallbackResponse, E>,
{
type Error = E;
fn dispatch(
&self,
request: &CallbackRequest,
payloads: &[PayloadEnvelope],
) -> Result<CallbackResponse, Self::Error> {
(self.f)(request, payloads)
}
}
#[derive(Debug)]
pub struct DefaultCallbackInvoker<C: ClientCallback> {
client: C,
}
impl<C: ClientCallback> DefaultCallbackInvoker<C> {
pub fn new(client: C) -> Self {
Self { client }
}
pub fn client(&self) -> &C {
&self.client
}
}
pub fn synthesize_request(plan: &RoutingPlan) -> CallbackRequest {
CallbackRequest {
schema_version: SCHEMA_VERSION.to_string(),
event: plan.event,
event_id: plan.event_id.clone(),
adapter_id: plan.adapter.adapter_id.clone(),
adapter_version: plan.adapter.adapter_version.clone(),
integration_mode: plan.integration_mode,
invocation_id: plan.invocation_id.clone(),
harness_session_id: None,
harness_run_id: None,
harness_task_id: None,
frame_context: plan.frame_context.clone(),
capability_snapshot_ref: plan.capability_snapshot_ref.clone(),
payload_refs: plan.payload_refs.clone(),
sequence: plan.sequence,
idempotency_key: plan.idempotency_key.clone(),
metadata: serde_json::Map::new(),
}
}
impl<C: ClientCallback> CallbackInvoker for DefaultCallbackInvoker<C> {
type Error = C::Error;
fn invoke(
&self,
plan: &RoutingPlan,
payloads: &[PayloadEnvelope],
) -> Result<CallbackResponse, Self::Error> {
let request = synthesize_request(plan);
self.client.dispatch(&request, payloads)
}
}