pdk-jwt-lib 1.10.0

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

//! # Expression Provider
//!
//! This module provides functionality for evaluating PDK script expressions
//! to extract values from request context for JWT processing.

use pdk_core::logger::error;
use pdk_script::{AttributesBinding, Script, TryFromValue};

/// From a [`Script`], it obtains a [`String`] with the result of the expression resolution.
pub struct ExpressionProvider {
    script: Script,
}

impl ExpressionProvider {
    pub fn new(script: Script) -> Self {
        Self { script }
    }

    pub fn provide(&mut self, binding: &dyn AttributesBinding) -> Option<String> {
        let mut evaluator = self.script.evaluator();
        evaluator.bind_attributes(binding);

        match evaluator.eval() {
            Err(e) => {
                error!("Error extracting data {e:?}");
                None
            }
            Ok(result) => String::try_from_value(result).ok(),
        }
    }
}

#[cfg(test)]
mod test {
    use super::ExpressionProvider;
    use mockall::mock;
    use pdk_script::Input::Attributes;
    use pdk_script::{Expression, HandlerAttributesBinding, ScriptingEngine};
    use serde_json;

    mock! {
        pub HeadersHandler {}
        impl pdk_core::classy::hl::HeadersHandler for HeadersHandler{
                fn headers(&self) -> Vec<(String, String)>;
                fn header(&self, name: &str) -> Option<String>;
                fn add_header(&self, name: &str, value: &str);
                fn set_header(&self, name: &str, value: &str);
                fn set_headers<'a>(&self, headers: Vec<(&'a str, &'a str)>);
                fn remove_header(&self, name: &str);
        }
    }

    #[test]
    pub fn update() {
        let header_value = "header1-value";
        let event = MockHeadersHandler::new();
        let pel = r#""P[[\":str\", \"0-20\", \"header1-value\"]]""#;
        let e: Expression = serde_json::from_str(pel).unwrap();
        let script = ScriptingEngine::script(&e)
            .input(Attributes)
            .compile()
            .unwrap();

        let mut ep = ExpressionProvider::new(script);

        let result = ep.provide(&HandlerAttributesBinding::partial(&event));

        assert_eq!(result, Some(header_value.to_string()))
    }
}