use crate::policy_context::authentication::{Authentication, AuthenticationHandler};
use classy::extract::context::FilterContext;
use classy::extract::{Extract, FromContext};
use classy::hl::context::{RequestContext, ResponseContext};
use classy::hl::{HeadersHandler, HttpClientResponse, StreamProperties};
use pdk_script::{
EvaluationError, Evaluator, HandlerAttributesBinding, IntoValue, PayloadBinding, Script, Value,
};
use std::convert::Infallible;
pub struct DefaultBindings {
stream: StreamProperties,
auth: Authentication,
}
impl FromContext<FilterContext> for DefaultBindings {
type Error = Infallible;
fn from_context(context: &FilterContext) -> Result<Self, Self::Error> {
let stream = context.extract()?;
let auth = context.extract()?;
Ok(Self { stream, auth })
}
}
impl FromContext<RequestContext> for DefaultBindings {
type Error = Infallible;
fn from_context(context: &RequestContext) -> Result<Self, Self::Error> {
let stream = context.extract()?;
let auth = context.extract()?;
Ok(Self { stream, auth })
}
}
impl<C> FromContext<ResponseContext<C>> for DefaultBindings {
type Error = Infallible;
fn from_context(context: &ResponseContext<C>) -> Result<Self, Self::Error> {
let stream = context.extract()?;
let auth = context.extract()?;
Ok(Self { stream, auth })
}
}
impl DefaultBindings {
pub fn evaluator<'a>(&'a self, script: &'a Script) -> DefaultEvaluator<'a> {
DefaultEvaluator {
provider: self,
evaluator: script.evaluator(),
}
}
}
pub struct DefaultEvaluator<'a> {
provider: &'a DefaultBindings,
evaluator: Evaluator<'a>,
}
impl DefaultEvaluator<'_> {
pub fn bind_vars<K: IntoValue>(&mut self, name: &str, value: K) {
self.evaluator.bind_vars(name, value)
}
pub fn bind_headers(&mut self, binding: &dyn HeadersHandler) {
let binding = HandlerAttributesBinding::new(binding, &self.provider.stream);
self.evaluator.bind_attributes(&binding)
}
pub fn bind_payload(&mut self, binding: &dyn PayloadBinding) {
self.evaluator.bind_payload(binding);
}
pub fn bind_http_client_response(&mut self, binding: &HttpClientResponse) {
self.evaluator.bind_attributes(binding);
self.evaluator.bind_payload(binding);
}
pub fn bind_authentication(&mut self) {
let auth = self.provider.auth.authentication().unwrap_or_default();
self.evaluator.bind_authentication(&auth)
}
pub fn is_ready(&self) -> bool {
self.evaluator.is_ready()
}
pub fn eval(self) -> Result<Value, EvaluationError> {
self.evaluator.eval()
}
}