pdk-flex-abi 1.7.0

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

//! API module for PDK Flex ABI
//!
//! This module provides the core traits and types for interacting with the Flex Gateway
//! runtime from within a policy implementation.

use pdk_core::classy::client::Service;
use pdk_core::client::service_name;

use crate::api::metadata::PolicyMetadata;
use crate::api::status::Status;
use crate::api::types::Bytes;
use crate::hostcalls;
use crate::hostcalls::{log, FlexLogLevel};

/// Metadata related types and functionality for PDK Flex policies.
pub mod metadata;

/// Status and error handling for PDK Flex operations.
pub mod status;

/// Common type definitions used across the PDK Flex ABI.
pub mod types;

/// Core trait defining the Flex ABI interface for policy implementations.
///
/// This trait provides the main interface that policies use to interact with the Flex Gateway
/// runtime, including logging, configuration access, and service management.
pub trait FlexAbi {
    /// Returns the metadata associated with the current policy.
    fn get_policy_metadata(&self) -> &PolicyMetadata;

    /// Returns the configuration data for the current policy.
    fn get_configuration(&self) -> &Bytes;

    /// Logs a message at TRACE level.
    fn log_trace(&self, msg: &str);

    /// Logs a message at DEBUG level.
    fn log_debug(&self, msg: &str);

    /// Logs a message at INFO level.
    fn log_info(&self, msg: &str);

    /// Logs a message at WARN level.
    fn log_warn(&self, msg: &str);

    /// Logs a message at ERROR level.
    fn log_error(&self, msg: &str);

    /// Creates a new service with the given configuration.
    ///
    /// # Arguments
    /// * `service` - The service configuration to create
    ///
    /// # Returns
    /// `Ok(())` on success, or a `Status` error if the operation fails.
    fn service_create(&self, service: Service) -> Result<(), Status>;

    /// Performs setup of the Flex ABI according to the enabled feature flags.
    ///
    /// # Returns
    /// `Ok(())` on success, or a `Status` error if the operation fails.
    fn setup(&self) -> Result<(), Status>;
}

pub(crate) struct FlexAbiImpl {
    pub(crate) metadata: PolicyMetadata,
    pub(crate) config: Bytes,
}

impl FlexAbi for FlexAbiImpl {
    fn get_policy_metadata(&self) -> &PolicyMetadata {
        &self.metadata
    }

    fn get_configuration(&self) -> &Bytes {
        &self.config
    }

    fn log_trace(&self, msg: &str) {
        log(FlexLogLevel::Trace, msg);
    }

    fn log_debug(&self, msg: &str) {
        log(FlexLogLevel::Debug, msg);
    }

    fn log_info(&self, msg: &str) {
        log(FlexLogLevel::Info, msg);
    }

    fn log_warn(&self, msg: &str) {
        log(FlexLogLevel::Warn, msg);
    }

    fn log_error(&self, msg: &str) {
        log(FlexLogLevel::Error, msg);
    }

    /// Registering services ABI functions
    fn service_create(&self, service: Service) -> Result<(), Status> {
        let service_name_optional_service = service_name(
            self.get_policy_metadata().policy_name(),
            service.uri().authority(),
        );

        hostcalls::service_create(
            service_name_optional_service.as_str(),
            self.get_policy_metadata().policy_namespace(),
            service.uri().to_string().as_str(),
        )?;

        Ok(())
    }

    fn setup(&self) -> Result<(), Status> {
        #[cfg(feature = "experimental_enable_stop_iteration")]
        hostcalls::enable_stop_iteration()?;

        Ok(())
    }
}