Skip to main content

autumn_plugin_aws_lambda/
activation.rs

1//! When the Lambda runtime loop starts. Verus twin: `Activation` in
2//! `verification/core.rs`.
3
4/// The variable that Lambda sets to the Runtime API address.
5pub const RUNTIME_API_ENV: &str = "AWS_LAMBDA_RUNTIME_API";
6
7/// The variable that sets the number of events that one environment
8/// handles at the same time (Lambda Managed Instances).
9const MAX_CONCURRENCY_ENV: &str = "AWS_LAMBDA_MAX_CONCURRENCY";
10
11/// Controls when the plugin starts the Lambda runtime loop.
12#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
13#[non_exhaustive]
14pub enum Activation {
15    /// Start only when Lambda sets `AWS_LAMBDA_RUNTIME_API`. This is the default.
16    #[default]
17    Auto,
18    /// Always start. Startup fails if a Lambda variable is missing.
19    Always,
20    /// Do not start. Use this to keep the plugin idle.
21    Never,
22}
23
24impl Activation {
25    /// Returns `true` if the loop must start.
26    pub(crate) const fn is_active(self, runtime_api_present: bool) -> bool {
27        match self {
28            Self::Auto => runtime_api_present,
29            Self::Always => true,
30            Self::Never => false,
31        }
32    }
33}
34
35/// Variables that `lambda_runtime` reads at start. It panics if one is missing.
36const REQUIRED_ENV: [&str; 4] = [
37    RUNTIME_API_ENV,
38    "AWS_LAMBDA_FUNCTION_NAME",
39    "AWS_LAMBDA_FUNCTION_MEMORY_SIZE",
40    "AWS_LAMBDA_FUNCTION_VERSION",
41];
42
43/// Returns the required Lambda variables that are missing or not valid.
44///
45/// `env` returns the value of one variable, or `None`. The memory size
46/// must be an `i32`. An empty result means that the runtime can start.
47pub fn missing_lambda_env(env: impl Fn(&str) -> Option<String>) -> Vec<&'static str> {
48    REQUIRED_ENV
49        .into_iter()
50        .filter(|name| {
51            env(name).is_none_or(|value| {
52                *name == "AWS_LAMBDA_FUNCTION_MEMORY_SIZE" && value.parse::<i32>().is_err()
53            })
54        })
55        .collect()
56}
57
58/// Returns the number of events to handle at the same time.
59///
60/// The rule is the same as in `lambda_runtime`: a positive `u32`, else 1.
61pub fn lambda_concurrency(env: impl Fn(&str) -> Option<String>) -> u32 {
62    env(MAX_CONCURRENCY_ENV)
63        .and_then(|value| value.parse::<u32>().ok())
64        .filter(|&n| n > 0)
65        .unwrap_or(1)
66}
67
68#[cfg(test)]
69mod tests {
70    use super::Activation;
71
72    #[test]
73    fn auto_starts_only_on_lambda() {
74        assert!(Activation::Auto.is_active(true));
75        assert!(!Activation::Auto.is_active(false));
76    }
77
78    #[test]
79    fn always_and_never_ignore_the_environment() {
80        for present in [true, false] {
81            assert!(Activation::Always.is_active(present));
82            assert!(!Activation::Never.is_active(present));
83        }
84    }
85
86    #[test]
87    fn default_activation_is_auto() {
88        assert_eq!(Activation::default(), Activation::Auto);
89    }
90}