Skip to content

[JULES] Scheduled Maintenance: Refactor redundant expect_* boilerplate in stdlib helpers - #427

Merged
logbie merged 1 commit into
mainfrom
refactor/dry-helpers-7776030076748350677
Mar 30, 2026
Merged

[JULES] Scheduled Maintenance: Refactor redundant expect_* boilerplate in stdlib helpers#427
logbie merged 1 commit into
mainfrom
refactor/dry-helpers-7776030076748350677

Conversation

@logbie

@logbie logbie commented Mar 27, 2026

Copy link
Copy Markdown
Collaborator

Summary of Changes

  • The Issue: src/stdlib/helpers.rs contained 7 heavily repeated expect_* functions (expect_number, expect_text, expect_list, expect_bool, expect_date, expect_time, expect_datetime). Each function followed identical logic: attempt to extract a specific type from a Value enum and return a RuntimeError on failure, resulting in unnecessary boilerplate.
  • The Rational: Consolidating this logic reduces visual noise, adheres to the DRY principle, ensures error messages remain completely uniform across the standard library, and simplifies the process of adding future type extractors.
  • The Solution: Implemented a new declarative macro generate_expect! to stamp out these implementations cleanly.

Verification Checklist

  • cargo fmt executed and passed.
  • cargo clippy returned no warnings or errors.
  • All cargo test suites passed (100% success rate).

PR created automatically by Jules for task 7776030076748350677 started by @logbie


Open with Devin

Summary by CodeRabbit

  • Refactor
    • Internal code improvements to helper functions for better maintainability and consistency.

…acro

Consolidates the repetitive `match` boilerplate found in the 7
`expect_*` functions (e.g. `expect_number`, `expect_text`, etc.)
into a single declarative macro. This ensures consistent error
messaging, simplifies the module, and drastically reduces code
duplication without altering behavior.

Co-authored-by: logbie <1138960+logbie@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 27, 2026 09:19
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Mar 27, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

A macro named generate_expect! was introduced to standardize seven type-specific value-extractor helper functions (expect_number, expect_text, expect_list, expect_bool, expect_date, expect_time, expect_datetime). Each function implementation was replaced with a macro invocation, preserving signatures while centralizing error handling and message formatting.

Changes

Cohort / File(s) Summary
Value-Extractor Helper Macro
src/stdlib/helpers.rs
Introduced generate_expect! macro to generate typed value extractors. Replaced seven expect_* functions with macro invocations, standardizing error messages to "Expected {type}, got {actual_type}" and centralizing RuntimeError construction. Function signatures unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 A macro hops in, tidy and spry,
Seven helpers dance—no longer shy,
Error messages unified, crystal-clear,
Less code duplication here and there! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: refactoring redundant expect_* boilerplate using a macro, which aligns with the file changes and PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/dry-helpers-7776030076748350677

Warning

Review ran into problems

🔥 Problems

Timed out fetching pipeline failures after 30000ms


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@devin-ai-integration devin-ai-integration Bot 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

Copilot AI 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.

Pull request overview

Refactors the stdlib expect_* type-extraction helpers by introducing a declarative macro to remove repeated boilerplate while keeping the same runtime error shape/messages across extractors.

Changes:

  • Added a generate_expect! macro to generate expect_* extractors with uniform error formatting.
  • Replaced the handwritten expect_number/text/list/bool/date/time/datetime implementations with macro invocations.
  • Kept per-extractor rustdoc by passing /// docs through the macro.

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

Comment thread src/stdlib/helpers.rs
Comment on lines +389 to +392
///
/// Returns an `Rc<str>` clone (incrementing the reference count) if the value is a Text variant.
/// The underlying string data is not copied, only the reference count is incremented.
///

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

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

These docs say the function returns an Rc<str> clone, but the return type is Arc<str> and the implementation uses Arc::clone. Please align the rustdoc with the actual Arc<str> API.

Copilot uses AI. Check for mistakes.
Comment thread src/stdlib/helpers.rs
$(#[$meta])*
pub fn $func_name(value: &Value) -> Result<$return_type, RuntimeError> {
match value {
Value::$variant(v) => Ok($extract(v)),

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

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

Ok($extract(v)) will not work when $extract is provided as a closure literal (as in the current invocations). The expansion becomes Ok(|x| ... (v)), which parses as a closure whose body calls v, and fails to compile. Wrap the extractor in parentheses (e.g., call it as ($extract)(v)) or require an identifier/path instead of a free-form expression.

Suggested change
Value::$variant(v) => Ok($extract(v)),
Value::$variant(v) => Ok(($extract)(v)),

Copilot uses AI. Check for mistakes.
Comment thread src/stdlib/helpers.rs
Comment on lines 184 to +188
/// let num = expect_number(&args[0])?;
/// Ok(Value::Number(num.abs()))
/// }
/// ```
pub fn expect_number(value: &Value) -> Result<f64, RuntimeError> {
match value {
Value::Number(n) => Ok(*n),
_ => Err(RuntimeError::new(
format!("Expected a number, got {}", value.type_name()),
0,
0,
)),
}
macro_rules! generate_expect {

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

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

The expect_number rustdoc block directly above generate_expect! now applies to the generate_expect macro (and duplicates the rustdoc you pass into generate_expect!(..., expect_number, ...)). Consider removing the earlier rustdoc block or moving the macro definition above it so the docs attach to the intended item.

Copilot uses AI. Check for mistakes.
Comment thread src/stdlib/helpers.rs
Comment on lines +381 to +383
/// Returns an `Rc<str>` to enable efficient memory sharing without copying the string
/// data. This is the standard way to extract text values in the WFL runtime.
///

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

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

These docs say Rc<str>, but Value::Text is Arc<str> and expect_text returns Arc<str>. Update the rustdoc to reference Arc<str> (and describe atomic ref-counting) to avoid misleading API consumers.

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/stdlib/helpers.rs`:
- Around line 381-405: The docs for expect_text incorrectly mention Rc<str> and
show Rc::from(...) even though the implementation uses Arc<str>/Arc::clone;
update the doc comments and the example to refer to Arc<str>, use Arc::from(...)
in the example, and mention Arc::clone where relevant so the documentation
matches the expect_text implementation and its return type.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 328cb58d-1e63-4ad1-90a1-3b4030fe928c

📥 Commits

Reviewing files that changed from the base of the PR and between 825a0e4 and f07c670.

📒 Files selected for processing (1)
  • src/stdlib/helpers.rs

Comment thread src/stdlib/helpers.rs
Comment on lines +381 to +405
/// Returns an `Rc<str>` to enable efficient memory sharing without copying the string
/// data. This is the standard way to extract text values in the WFL runtime.
///
/// # Arguments
///
/// * `value` - The WFL Value to extract from
///
/// # Returns
///
/// Returns an `Rc<str>` clone (incrementing the reference count) if the value is a Text variant.
/// The underlying string data is not copied, only the reference count is incremented.
///
/// # Errors
///
/// Returns `RuntimeError` if the value is not a Text, with an error message
/// indicating the expected type and the actual type received.
///
/// # Examples
///
/// ```ignore
/// pub fn native_uppercase(args: Vec<Value>) -> Result<Value, RuntimeError> {
/// check_arg_count("uppercase", &args, 1)?;
/// let text = expect_text(&args[0])?;
/// Ok(Value::Text(Rc::from(text.to_uppercase())))
/// }

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify remaining Rc/Arc doc inconsistencies in this helper file.
rg -n 'Rc<str>|Rc::from\(text\.to_uppercase\(\)\)|Arc<str>|Arc::from' src/stdlib/helpers.rs

Repository: WebFirstLanguage/wfl

Length of output: 686


Fix Arc/Rc mismatch in expect_text documentation.

The generated function returns Arc<str>, but the doc block still incorrectly describes Rc<str> and uses Rc::from(...) in the example. Lines 381 and 390 reference Rc<str>, and line 404 shows Rc::from(text.to_uppercase()), but the actual implementation (lines 409–411) uses Arc<str> and Arc::clone.

📝 Proposed doc fix
-    /// Returns an `Rc<str>` to enable efficient memory sharing without copying the string
+    /// Returns an `Arc<str>` to enable efficient memory sharing without copying the string
@@
-    /// Returns an `Rc<str>` clone (incrementing the reference count) if the value is a Text variant.
+    /// Returns an `Arc<str>` clone (incrementing the reference count) if the value is a Text variant.
@@
-    ///     Ok(Value::Text(Rc::from(text.to_uppercase())))
+    ///     Ok(Value::Text(Arc::from(text.to_uppercase())))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// Returns an `Rc<str>` to enable efficient memory sharing without copying the string
/// data. This is the standard way to extract text values in the WFL runtime.
///
/// # Arguments
///
/// * `value` - The WFL Value to extract from
///
/// # Returns
///
/// Returns an `Rc<str>` clone (incrementing the reference count) if the value is a Text variant.
/// The underlying string data is not copied, only the reference count is incremented.
///
/// # Errors
///
/// Returns `RuntimeError` if the value is not a Text, with an error message
/// indicating the expected type and the actual type received.
///
/// # Examples
///
/// ```ignore
/// pub fn native_uppercase(args: Vec<Value>) -> Result<Value, RuntimeError> {
/// check_arg_count("uppercase", &args, 1)?;
/// let text = expect_text(&args[0])?;
/// Ok(Value::Text(Rc::from(text.to_uppercase())))
/// }
/// Returns an `Arc<str>` to enable efficient memory sharing without copying the string
/// data. This is the standard way to extract text values in the WFL runtime.
///
/// # Arguments
///
/// * `value` - The WFL Value to extract from
///
/// # Returns
///
/// Returns an `Arc<str>` clone (incrementing the reference count) if the value is a Text variant.
/// The underlying string data is not copied, only the reference count is incremented.
///
/// # Errors
///
/// Returns `RuntimeError` if the value is not a Text, with an error message
/// indicating the expected type and the actual type received.
///
/// # Examples
///
///
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/stdlib/helpers.rs` around lines 381 - 405, The docs for expect_text
incorrectly mention Rc<str> and show Rc::from(...) even though the
implementation uses Arc<str>/Arc::clone; update the doc comments and the example
to refer to Arc<str>, use Arc::from(...) in the example, and mention Arc::clone
where relevant so the documentation matches the expect_text implementation and
its return type.

@logbie
logbie merged commit 69a2476 into main Mar 30, 2026
17 checks passed
@logbie
logbie deleted the refactor/dry-helpers-7776030076748350677 branch March 30, 2026 05:37
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.

2 participants