Skip to main content

kinetics_parser/
function.rs

1use crate::params::Params;
2use color_eyre::eyre;
3use serde::{Deserialize, Serialize};
4use std::fmt::Display;
5
6/// The kind of function
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub enum Role {
9    Endpoint,
10    Cron,
11    Worker,
12}
13
14impl Display for Role {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        let str = match self {
17            Role::Endpoint => "endpoint",
18            Role::Cron => "cron",
19            Role::Worker => "worker",
20        };
21
22        write!(f, "{}", str)
23    }
24}
25
26/// Represents a function in the source code
27#[derive(Debug, Clone)]
28pub struct ParsedFunction {
29    /// Name of the function, parsed from the function definition
30    pub rust_function_name: String,
31
32    /// Path to the file where function is defined
33    pub relative_path: String,
34
35    /// The kind of function (endpoint, cron, or worker), without parameters
36    pub role: Role,
37
38    /// The workload-specific parameters parsed from the kinetics macro attribute
39    pub params: Params,
40}
41
42impl ParsedFunction {
43    /// Convert a path to CamelCase name
44    pub fn path_to_name(path: &str) -> String {
45        path.split(&['.', '/'])
46            .filter(|s| !s.eq(&"rs"))
47            .map(|s| match s.chars().next() {
48                Some(first) => first.to_uppercase().collect::<String>() + &s[1..],
49                None => String::new(),
50            })
51            .collect::<String>()
52            .replacen("Src", "", 1)
53    }
54
55    /// Generate lambda function name out of Rust function name or macro attribute
56    ///
57    /// By default use the Rust function plus crate path as the function name. Convert
58    /// some-name to SomeName, and do other transformations in order to comply with Lambda
59    /// function name requirements.
60    pub fn func_name(&self, is_local: bool) -> eyre::Result<String> {
61        let rust_name = &self.rust_function_name;
62        let full_path = format!("{}/{rust_name}", self.relative_path);
63        let default_func_name = Self::path_to_name(&full_path);
64        let name = self.params.name().unwrap_or(&default_func_name);
65
66        if name.len() > 64 {
67            Err(eyre::eyre!(
68                "Function name is longer than 64 chars: {}",
69                name
70            ))
71        } else {
72            // TODO Check the name for uniqueness
73            Ok(format!("{}{}", name, if is_local { "Local" } else { "" }))
74        }
75    }
76}