Skip to content

Extend expression engine with built-in functions, new operators, and Value::map()#62

Merged
ashyanSpada merged 3 commits intomasterfrom
copilot/extend-repo-capabilities
Apr 9, 2026
Merged

Extend expression engine with built-in functions, new operators, and Value::map()#62
ashyanSpada merged 3 commits intomasterfrom
copilot/extend-repo-capabilities

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 8, 2026

The engine had only 4 built-in functions (min, max, sum, mul) and lacked common math, string, list, and map utilities. This PR adds 18 new built-in functions, 2 new infix operators, and the missing Value::map() accessor.

New built-in functions

Math: abs, floor, ceil, round, avg, pow, sqrt

String/conversion: len (string/list/map), upper, lower, trim, concat, str, num

List: first, last

Map: keys, values

New infix operators

  • contains — string containment, completing the beginWith/endWith/in family
    "hello world" contains "world"  // true
    
  • notIn — list non-membership, complement of the existing in operator
    1 notIn [2, 3, 4]  // true
    

Value::map() accessor

ShouldBeMap error variant existed but had no corresponding extractor method. Added Value::map() -> Result<Vec<(Value, Value)>> to mirror Value::list(), used internally by keys/values.

Notes

  • contains is registered as an infix operator only (not a function) because the tokenizer prioritizes operator recognition over function names for alphabetic tokens — consistent with how beginWith, endWith, and in are handled.
  • README updated with new operator descriptions and a Built-in Functions reference table.

Copilot AI changed the title [WIP] Extend the capabilities of the repository Extend expression engine with built-in functions, new operators, and Value::map() Apr 8, 2026
Copilot AI requested a review from ashyanSpada April 8, 2026 20:24
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 9, 2026

Codecov Report

❌ Patch coverage is 97.95918% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.66%. Comparing base (257b200) to head (f49427e).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
src/function.rs 97.72% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master      #62      +/-   ##
==========================================
+ Coverage   89.56%   90.66%   +1.10%     
==========================================
  Files          11       11              
  Lines        1064     1211     +147     
==========================================
+ Hits          953     1098     +145     
- Misses        111      113       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ashyanSpada
Copy link
Copy Markdown
Owner

@copilot check failed. Please review your changes and conduct related fix.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 9, 2026

@copilot check failed. Please review your changes and conduct related fix.

The CI failure was a cargo fmt --check issue — rustfmt expected slightly different formatting in two spots in src/function.rs. Fixed in f49427e by running cargo fmt.

@ashyanSpada ashyanSpada marked this pull request as ready for review April 9, 2026 02:14
Copilot AI review requested due to automatic review settings April 9, 2026 02:14
@ashyanSpada ashyanSpada merged commit 61543e9 into master Apr 9, 2026
16 checks passed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends the expression engine with additional built-in utility functions, adds contains/notIn infix operators, and introduces a missing Value::map() accessor to support map operations.

Changes:

  • Added Value::map() accessor plus unit tests.
  • Registered new infix operators notIn (list non-membership) and contains (string containment), with tests.
  • Added a set of new built-in functions (math/string/list/map) and documented them in the README.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
src/value.rs Adds Value::map() extractor to complement existing accessors and supports map-focused built-ins.
src/operator.rs Registers notIn/contains as infix operators and adds operator-level tests.
src/function.rs Implements new built-in functions and adds a dedicated test module for them.
README.md Documents the new operators and provides a built-in functions reference table.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/function.rs
Comment on lines +82 to +88
"abs",
Arc::new(|params| {
if params.is_empty() {
return Err(Error::ParamEmpty("abs".to_string()));
}
let val = params.into_iter().next().unwrap().decimal()?;
Ok(Value::Number(val.abs()))
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

abs (and several other unary functions added here) only checks params.is_empty() and then uses the first argument, silently ignoring any extra arguments (e.g., abs(1, 2) would return 1). Since the README documents these as single-argument functions, consider enforcing the exact arity (e.g., params.len() == 1) and returning Error::ParamInvalid() otherwise.

Copilot uses AI. Check for mistakes.
Comment thread src/function.rs
Comment on lines +141 to +149
"pow",
Arc::new(|params| {
if params.len() < 2 {
return Err(Error::ParamEmpty("pow".to_string()));
}
let mut iter = params.into_iter();
let base = iter.next().unwrap().float()?;
let exp = iter.next().unwrap().float()?;
Ok(Value::from(base.powf(exp)))
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

pow uses Error::ParamEmpty("pow") when fewer than 2 args are provided, but that error message is misleading for the pow(2) case (params aren’t empty, just insufficient). It also ignores any extra args. Consider validating the arity explicitly (exactly 2 args) and returning Error::ParamInvalid() on mismatch.

Copilot uses AI. Check for mistakes.
Comment thread src/function.rs
Comment on lines +147 to +161
let base = iter.next().unwrap().float()?;
let exp = iter.next().unwrap().float()?;
Ok(Value::from(base.powf(exp)))
}),
);

self.register(
"sqrt",
Arc::new(|params| {
if params.is_empty() {
return Err(Error::ParamEmpty("sqrt".to_string()));
}
let val = params.into_iter().next().unwrap().float()?;
Ok(Value::from(val.sqrt()))
}),
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

pow/sqrt return Value::from(f64) results. In Value::from(f64) the conversion uses Decimal::from_f64(...).unwrap_or_default(), so non-finite results (NaN/±inf) or values outside Decimal’s representable range will silently turn into 0 instead of erroring. Consider converting via Decimal::from_f64(...) here and returning an error (e.g., Error::InvalidFloat/Error::InvalidNumber) when conversion fails or the result is non-finite.

Copilot uses AI. Check for mistakes.
Comment thread src/operator.rs

#[cfg(test)]
mod tetst {
#[cfg(test)]
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

There are two consecutive #[cfg(test)] attributes applied to the tests module, which is redundant. Consider removing one of them to keep the module declaration clean.

Suggested change
#[cfg(test)]

Copilot uses AI. Check for mistakes.
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