pdk-classy 1.3.0-alpha.0

PDK Classy
Documentation
// Copyright 2023 Salesforce, Inc. All rights reserved.
use std::{cell::RefCell, marker::PhantomData, rc::Rc};

use crate::event::{After, BodyEvent, EventData, HeadersAccessor, HeadersEvent};

use super::{
    body::BodyExchange,
    dynamic_exchange::{DynamicExchange, ExchangeEvent},
    entity::HeadersHandler,
};
pub struct HeadersExchange<H, B> {
    pub(super) contains_body: bool,
    exchange: Rc<RefCell<DynamicExchange>>,
    _events: PhantomData<(H, B)>,
}

impl<H, B> HeadersExchange<H, B>
where
    H: HeadersEvent + ExchangeEvent,
    B: BodyEvent + After<H> + ExchangeEvent,
{
    pub(super) fn new(exchange: Rc<RefCell<DynamicExchange>>, contains_body: bool) -> Self {
        Self {
            contains_body,
            exchange,
            _events: PhantomData,
        }
    }
}

impl<H, B> HeadersExchange<H, B>
where
    H: HeadersEvent + ExchangeEvent,
{
    pub fn with_event_data<F, T>(&self, op: F) -> T
    where
        for<'e> F: FnOnce(&EventData<'e, H>) -> T,
    {
        let exchange = self.exchange.borrow();
        let exchange = exchange
            .get::<H>()
            .expect("Exchange should be in Headers event");
        let event = exchange
            .event_data()
            .expect("Exchange should be in Headers event");

        op(&event)
    }
}

impl<H, B> HeadersExchange<H, B>
where
    H: HeadersEvent + ExchangeEvent,
    B: BodyEvent + After<H> + ExchangeEvent + 'static,
    for<'e> EventData<'e, H>: HeadersAccessor,
{
    pub async fn into_body_state(self) -> BodyExchange<B> {
        BodyExchange::new(self.exchange, self.contains_body).await
    }

    pub fn handler(&self) -> &dyn HeadersHandler {
        self
    }
}

impl<H, B> HeadersHandler for HeadersExchange<H, B>
where
    H: HeadersEvent + ExchangeEvent,
    for<'e> EventData<'e, H>: HeadersAccessor,
{
    fn headers(&self) -> Vec<(String, String)> {
        self.with_event_data(|e| e.headers())
    }

    fn header(&self, name: &str) -> Option<String> {
        self.with_event_data(|e| e.header(name))
    }

    fn add_header(&self, name: &str, value: &str) {
        self.with_event_data(|e| e.add_header(name, value))
    }

    fn set_header(&self, name: &str, value: &str) {
        self.with_event_data(|e| e.set_header(name, value))
    }

    fn set_headers(&self, headers: Vec<(&str, &str)>) {
        self.with_event_data(|e| e.set_headers(headers))
    }

    fn remove_header(&self, name: &str) {
        self.with_event_data(|e| e.remove_header(name))
    }
}