pdk-classy 1.3.0-alpha.0

PDK Classy
Documentation
// Copyright 2023 Salesforce, Inc. All rights reserved.
use std::future::Future;

/// A handler for accesing the headers of the current HTTP Flow.
pub trait HeadersHandler {
    /// Returns a list of headers represented by pairs of name and value.
    fn headers(&self) -> Vec<(String, String)>;

    /// Returns a header by `name` if it exists.
    fn header(&self, name: &str) -> Option<String>;

    /// Adds a header `value` by `name`.
    /// If there is a header with the same `name`, this method will keep that and adding another
    /// header entry with the same `name` and the new `value`.
    fn add_header(&self, name: &str, value: &str);

    /// Sets a header `value` by `name`.
    /// If there is a header with the same `name`, this method will replace the header `value`.
    fn set_header(&self, name: &str, value: &str);

    /// Sets a list of headers represented by pairs of name and value.
    fn set_headers(&self, headers: Vec<(&str, &str)>);

    /// Removes a header by `name` if it exists.
    fn remove_header(&self, name: &str);
}

/// The error for [`BodyHandler`] operations.
#[derive(Clone, PartialEq, Eq, Debug, thiserror::Error)]
pub enum BodyError {
    /// The current HTTP Flow does not have a body.
    #[error("Body not sent")]
    BodyNotSent,

    /// The body size exceeds what the low-level host allows.
    #[error("Exceeded body size: {0}")]
    ExceededBodySize(usize),
}

/// A handler for accesing the body of the current HTTP Flow.
pub trait BodyHandler {
    /// Returns the body of the current HTTP Flow.
    fn body(&self) -> Vec<u8>;

    /// Sets the `body` of the current HTTP Flow in binary format.
    ///
    /// # Errors
    ///
    /// This method will return an error in the following situations, but is not
    /// limited to just these cases:
    ///
    /// * The current HTTP Flow does not have a body and it can not be injected.
    /// * The `body` size exceeds what the low-level host allows.
    fn set_body(&self, body: &[u8]) -> Result<(), BodyError>;
}

/// Abstract state of the HTTP Flow state-machine allowed to be moved into the Body state.
pub trait IntoBodyState {
    /// Concrete type for Body state of the Flow state-machine.
    type BodyState: BodyState;

    /// A [`Future`] that will be completed when the Body state is reached.
    type BodyStateFuture: Future<Output = Self::BodyState>;

    /// Moves the current state into the Body state of the HTTP Flow state-machine.
    /// The [`Future`] returned by this method can be cancelled.
    #[must_use]
    fn into_body_state(self) -> Self::BodyStateFuture;
}

/// Abstract initial state of the HTTP Flow state-machine.
pub trait EntityState: IntoBodyState {
    /// Concrete type for Headers state of the Flow state-machine.
    type HeadersState: HeadersState;

    /// A [`Future`] that will be completed when the Headers state is reached.
    type HeadersStateFuture: Future<Output = Self::HeadersState>;

    /// Moves the current initial state into the Headers state of the HTTP Flow state-machine.
    /// The [`Future`] returned by this method can be cancelled.
    #[must_use]
    fn into_headers_state(self) -> Self::HeadersStateFuture;
}

/// Abstract Headers state of the HTTP Flow state-machine.
pub trait HeadersState: IntoBodyState {
    /// Returns a handler for accesing the headers of the current HTTP Flow.
    fn handler(&self) -> &dyn HeadersHandler;

    /// Returns [`true`] if the current HTTP Flow contains body.
    fn contains_body(&self) -> bool;
}

/// Abstract Body state of the HTTP Flow state-machine.
pub trait BodyState {
    /// Returns a handler for accesing the body of the current HTTP Flow.
    fn handler(&self) -> &dyn BodyHandler;

    /// Returns [`true`] if the current HTTP Flow contains body.
    fn contains_body(&self) -> bool;
}