Skip to content

chore(guard): Refactor functions into enum / handle no args - #551

Merged
dannyvassallo merged 6 commits into
aws-cloudformation:mainfrom
dannyvassallo:refactor_functions
Aug 22, 2024
Merged

dannyvassallo merged 6 commits into
aws-cloudformation:mainfrom
dannyvassallo:refactor_functions

Conversation

@dannyvassallo

@dannyvassallo dannyvassallo commented Aug 19, 2024 •

Copy link
Copy Markdown
Contributor

Issue #, if available: None

Description of changes:

Uses an enum instead of hardcoded strings for function names and allows for function invocation without arguments.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@joshfried-aws joshfried-aws left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about adding an impl for the Function enum like this

pub fn get_expected_number_of_args(&self) -> usize {
        match self {
            Function::Join => 2,
            Function::Substring | Function::RegexReplace => 3,
            Function::Count
            | Function::JsonParse
            | Function::ToUpper
            | Function::ToLower
            | Function::URLDecode
            | Function::ParseString
            | Function::ParseBoolean
            | Function::ParseFloat
            | Function::ParseInt
            | Function::ParseChar => 1,
        }
    }

This would allow us to move up the check for the num of params to the time of parsing like so

fn function_expr(input: Span) -> IResult<Span, FunctionExpr> {
    let location = FileLocation {
        file_name: input.extra,
        line: input.location_line(),
        column: input.get_column() as u32,
    };
    let (input, (name, parameters)) = call_expr(input)?;

    let name = Function::try_from(name.as_str()).map_err(|e| {
        nom::Err::Error(ParserError {
            context: e.to_string(),
            span: input,
            kind: ErrorKind::AlphaNumeric,
        })
    })?;

    if parameters.len() != name.get_expected_number_of_args() {
        return Err(nom::Err::Error(ParserError {
            context: format!(
                "function: {name} requires: {} parameters to be passed, but received: {}",
                name.get_expected_number_of_args(),
                parameters.len()
            ),
            span: input,
            kind: ErrorKind::AlphaNumeric,
        }));
    }

    Ok((
        input,
        FunctionExpr {
            location,
            name,
            parameters,
        },
    ))
}

Comment thread guard/src/rules/exprs.rs Resolved
Comment thread guard/src/rules/eval_context.rs Resolved
Comment thread guard/src/rules/eval_context.rs Resolved
Comment thread guard/src/rules/eval_context.rs Resolved

@joshfried-aws joshfried-aws left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few minor comments, imo nothing is major / blocking. Great work on this Dan, this is a much cleaner approach than the initial implementation 😎

Comment thread guard/src/rules/eval_context.rs Resolved
Comment thread guard/src/rules/eval_context.rs Resolved
@dannyvassallo dannyvassallo changed the title chore(guard): Refactor functions into enum / handle optional & no args chore(guard): Refactor functions into enum / handle no args Aug 22, 2024
@dannyvassallo
dannyvassallo merged commit ddc1ba4 into aws-cloudformation:main Aug 22, 2024
joshfried-aws pushed a commit to joshfried-aws/cloudformation-guard that referenced this pull request Nov 22, 2024
…dformation#551)

* chore(guard): Refactor functions into enum / handle optional & no args
* chore(guard): Update parser_tests.rs
* chore(guard): Address feedback and update tests
* chore(guard): Use function name in tests and address feedback
* chore(guard): implement callable
* chore(guard): Refactor functions into callable structs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants