use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::execution::{ActionId, ExternalError, InvocationContext, OperationId};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FacadeRequest {
pub operation_id: OperationId,
pub target: String,
pub input: Value,
pub response_detail: crate::execution::ResponseDetail,
}
pub use crate::{InteractionCard, InteractionKind, InteractionTone};
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PreparedAction {
pub action_id: ActionId,
pub operation_id: OperationId,
pub card: InteractionCard,
#[serde(default)]
pub payload: Value,
pub revision: u64,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct FacadeResult {
#[serde(deserialize_with = "deserialize_response")]
pub value: Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context_invalidation: Option<crate::execution::ContextInvalidation>,
}
#[async_trait]
pub trait AppFacade: Send + Sync {
async fn invoke(
&self,
context: &InvocationContext,
request: FacadeRequest,
) -> Result<FacadeResult, ExternalError>;
async fn prepare(
&self,
context: &InvocationContext,
request: FacadeRequest,
) -> Result<PreparedAction, ExternalError>;
async fn commit(
&self,
context: &InvocationContext,
action: PreparedAction,
) -> Result<FacadeResult, ExternalError>;
async fn reject(
&self,
context: &InvocationContext,
action: PreparedAction,
) -> Result<(), ExternalError>;
}
fn deserialize_response<'de, D: serde::Deserializer<'de>>(
deserializer: D,
) -> Result<Value, D::Error> {
use serde::de::Error;
let response = crate::execution::FacadeResponse::deserialize(deserializer)?;
serde_json::to_value(response).map_err(D::Error::custom)
}