use bytes::Bytes;
use std::any::Any;
use std::collections::HashMap;
use async_trait::async_trait;
use serde_json::Value;
use crate::layers::l7::container::Container;
use crate::resources::kv::KvStore;
use crate::resources::templates::{context::L7Context, context::SimpleContext, resolve_inputs};
#[async_trait]
pub trait ExecutionContext: Send {
fn kv_mut(&mut self) -> &mut KvStore;
async fn resolve_inputs(&mut self, inputs: &HashMap<String, Value>) -> HashMap<String, Value>;
fn as_any_mut(&mut self) -> &mut (dyn Any + Send);
fn insert_payload(&mut self, _key: String, _data: Bytes) {}
}
pub struct TransportContext<'a> {
pub kv: &'a mut KvStore,
pub payloads: ahash::AHashMap<String, Bytes>,
}
#[async_trait]
impl<'a> ExecutionContext for TransportContext<'a> {
fn kv_mut(&mut self) -> &mut KvStore {
self.kv
}
async fn resolve_inputs(&mut self, inputs: &HashMap<String, Value>) -> HashMap<String, Value> {
let mut simple_ctx = SimpleContext {
kv: self.kv,
payloads: Some(&self.payloads),
};
resolve_inputs(inputs, &mut simple_ctx).await
}
fn as_any_mut(&mut self) -> &mut (dyn Any + Send) {
self.kv as &mut (dyn Any + Send)
}
fn insert_payload(&mut self, key: String, data: Bytes) {
self.payloads.insert(key, data);
}
}
pub struct ApplicationContext<'a> {
pub container: &'a mut Container,
}
#[async_trait]
impl<'a> ExecutionContext for ApplicationContext<'a> {
fn kv_mut(&mut self) -> &mut KvStore {
&mut self.container.kv
}
async fn resolve_inputs(&mut self, inputs: &HashMap<String, Value>) -> HashMap<String, Value> {
let mut l7_ctx = L7Context {
container: self.container,
};
resolve_inputs(inputs, &mut l7_ctx).await
}
fn as_any_mut(&mut self) -> &mut (dyn Any + Send) {
self.container as &mut (dyn Any + Send)
}
}