pdk-classy 1.9.0-alpha.3

PDK Classy
Documentation
// Copyright (c) 2026, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

use crate::{
    handler::{Handler, IntoHandler},
    hl::{
        bootstrap::{DualFilter, RequestFilter, ResponseFilter},
        context::{RequestContext, ResponseContext},
        state::{CreateHandler, DoneHandler, EmptyCreateHandler},
        IntoFlow,
    },
};

pub struct FilterBuilder<Sf = EmptyCreateHandler, Req = (), Res = (), Done = ()> {
    state_factory: Sf,
    request_filter: Req,
    response_filter: Res,
    done_handler: Done,
}

impl FilterBuilder {
    pub fn new() -> Self {
        Self {
            state_factory: EmptyCreateHandler,
            request_filter: (),
            response_filter: (),
            done_handler: (),
        }
    }

    pub fn on_create<Sf: CreateHandler>(self, state_factory: Sf) -> FilterBuilder<Sf> {
        FilterBuilder {
            state_factory,
            request_filter: self.request_filter,
            response_filter: self.response_filter,
            done_handler: self.done_handler,
        }
    }
}

impl Default for FilterBuilder {
    fn default() -> Self {
        Self::new()
    }
}

impl<Sf, Done> FilterBuilder<Sf, (), (), Done>
where
    Sf: CreateHandler,
{
    pub fn on_request<I, Req>(
        self,
        request_filter: Req,
    ) -> FilterBuilder<Sf, Req::Handler, (), Done>
    where
        Req: IntoHandler<RequestContext<Sf::State>, I>,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: request_filter.into_handler(),
            response_filter: self.response_filter,
            done_handler: self.done_handler,
        }
    }

    pub fn on_response<I, Res>(
        self,
        response_filter: Res,
    ) -> FilterBuilder<Sf, (), Res::Handler, Done>
    where
        Res: IntoHandler<ResponseContext<(), Sf::State>, I, Output = ()>,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: self.request_filter,
            response_filter: response_filter.into_handler(),
            done_handler: self.done_handler,
        }
    }

    pub fn on_done<D>(self, done_handler: D) -> FilterBuilder<Sf, (), (), D>
    where
        D: DoneHandler<Sf::State>,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: self.request_filter,
            response_filter: self.response_filter,
            done_handler,
        }
    }
}

impl<Sf, Req, Done> FilterBuilder<Sf, Req, (), Done>
where
    Sf: CreateHandler,
    Req: Handler<RequestContext<Sf::State>, Output: IntoFlow>,
{
    pub fn on_response<I, Res>(
        self,
        response_filter: Res,
    ) -> FilterBuilder<Sf, Req, Res::Handler, Done>
    where
        Res: IntoHandler<
            ResponseContext<<Req::Output as IntoFlow>::RequestData, Sf::State>,
            I,
            Output: IntoFlow,
        >,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: self.request_filter,
            response_filter: response_filter.into_handler(),
            done_handler: self.done_handler,
        }
    }

    pub fn on_done<D>(self, done_handler: D) -> FilterBuilder<Sf, Req, (), D>
    where
        D: DoneHandler<Sf::State>,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: self.request_filter,
            response_filter: self.response_filter,
            done_handler,
        }
    }
}

impl<Sf, Req, Done> FilterBuilder<Sf, Req, (), Done>
where
    Req: Handler<RequestContext<Sf::State>>,
    Sf: CreateHandler,
{
    /// Builds a Request Filter
    pub fn build(self) -> RequestFilter<Req, Sf, Done> {
        RequestFilter {
            request_handler: self.request_filter,
            state_factory: self.state_factory,
            done_handler: self.done_handler,
        }
    }
}

impl<Sf, Res, Done> FilterBuilder<Sf, (), Res, Done>
where
    Res: Handler<ResponseContext<(), Sf::State>>,
    Sf: CreateHandler,
{
    /// Builds a response filter
    pub fn build(self) -> ResponseFilter<Res, Sf, Done> {
        ResponseFilter {
            response_handler: self.response_filter,
            state_factory: self.state_factory,
            done_handler: self.done_handler,
        }
    }

    pub fn on_done<D>(self, done_handler: D) -> FilterBuilder<Sf, (), Res, D>
    where
        D: DoneHandler<Sf::State>,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: self.request_filter,
            response_filter: self.response_filter,
            done_handler,
        }
    }
}

impl<Sf, Req, Res, Done> FilterBuilder<Sf, Req, Res, Done>
where
    Req: Handler<RequestContext<Sf::State>, Output: IntoFlow>,
    Res: Handler<ResponseContext<<Req::Output as IntoFlow>::RequestData, Sf::State>>,
    Sf: CreateHandler,
{
    /// Builds a Request/Response filter
    pub fn build(self) -> DualFilter<Req, Res, Sf, Done> {
        DualFilter {
            request_handler: self.request_filter,
            response_handler: self.response_filter,
            state_factory: self.state_factory,
            done_handler: self.done_handler,
        }
    }

    pub fn on_done<D>(self, done_handler: D) -> FilterBuilder<Sf, Req, Res, D>
    where
        D: DoneHandler<Sf::State>,
    {
        FilterBuilder {
            state_factory: self.state_factory,
            request_filter: self.request_filter,
            response_filter: self.response_filter,
            done_handler,
        }
    }
}