Skip to content

switch to the solidity formatter#126

Merged
thedavidmeister merged 2 commits intomainfrom
fix/formatter
Sep 8, 2025
Merged

switch to the solidity formatter#126
thedavidmeister merged 2 commits intomainfrom
fix/formatter

Conversation

@0xgleb
Copy link
Copy Markdown
Contributor

@0xgleb 0xgleb commented Sep 8, 2025

Motivation

Solidity formatter was implemented

Solution

Switch to the proper formatting logic instead of using the temporary workaround

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

  • New Features

    • Float formatting now supports a configurable significant-figures limit while keeping a default of 18.
  • Refactor

    • JavaScript formatting API renamed and simplified; the previous fixed-precision export removed (breaking change). Use the new API that accepts a precision limit.
  • Documentation

    • Examples and guidance updated to show configurable precision and the 18-default behavior.
  • Tests

    • Tests updated to use the new formatting API and adjusted expected decimal output.

@0xgleb 0xgleb self-assigned this Sep 8, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 8, 2025

Walkthrough

The Float formatting API replaces the fixed 18-decimal export with a configurable-significant-figures API: a new Rust method format_with_limit(sig_figs_limit) is added, format() delegates to it with default 18, the old format18/format18_js export is removed and replaced by formatWithLimit for JS, and tests/docs updated.

Changes

Cohort / File(s) Summary
JS WASM export update
crates/float/src/js_api.rs
Replaces wasm export format18_js (js_name = "format18") with format_with_limit_js(sig_figs_limit: u32) (js_name = "formatWithLimit"); delegates to self.format_with_limit(sig_figs_limit).
Core formatting API refactor
crates/float/src/lib.rs
Adds Float::format_with_limit(self, sig_figs_limit: u32) -> Result<String, FloatError>; removes format18(); makes format() call format_with_limit(18); updates docs/tests and routes to DecimalFloat::formatCall with a parameterized sigFigsLimit.
JS tests alignment
test_js/float.test.ts
Updates tests to call format() (which uses default 18) instead of format18() and adjusts test descriptions/assertions accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor JS as JS Caller
  participant WASM as WASM Export<br/>(formatWithLimit)
  participant Rust as Float::format_with_limit
  participant ABI as DecimalFloat::formatCall

  JS->>WASM: formatWithLimit(sig_figs_limit)
  WASM->>Rust: format_with_limit(sig_figs_limit)
  Rust->>ABI: formatCall(sigFigsLimit = sig_figs_limit)
  ABI-->>Rust: formatted String / error
  Rust-->>WASM: Result<String, FloatError>
  WASM-->>JS: String / error
Loading
sequenceDiagram
  autonumber
  actor JS as JS Caller
  participant WASM as WASM Export<br/>(format)
  participant Rust as Float::format
  participant Rust2 as Float::format_with_limit

  JS->>WASM: format()
  WASM->>Rust: format()
  Rust->>Rust2: format_with_limit(18)
  Rust2-->>Rust: Result<String, FloatError>
  Rust-->>WASM: Result<String, FloatError>
  WASM-->>JS: String / error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • hardyjosh
  • findolor

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 216f5c3 and e9ce531.

📒 Files selected for processing (2)
  • crates/float/src/js_api.rs (2 hunks)
  • crates/float/src/lib.rs (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#59
File: crates/float/src/lib.rs:233-242
Timestamp: 2025-06-17T10:17:56.205Z
Learning: In the rainlanguage/rain.math.float repository, the maintainer 0xgleb prefers to handle documentation additions and improvements in separate issues rather than inline with feature PRs.
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#119
File: test/src/lib/format/LibFormatDecimalFloat.toDecimalString.t.sol:174-175
Timestamp: 2025-09-02T09:33:32.513Z
Learning: The LibFormatDecimalFloat.toDecimalString function in src/lib/format/LibFormatDecimalFloat.sol does not include rounding logic. It formats decimal floats as-is without rounding values based on significant figures limits.
🧬 Code graph analysis (1)
crates/float/src/lib.rs (1)
crates/float/src/evm.rs (1)
  • execute_call (51-56)
🔇 Additional comments (1)
crates/float/src/lib.rs (1)

1195-1201: LGTM: test expectation matches default formatter output

The updated expectations for abs().format() are consistent with the decimal (non-exponential) output.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/formatter

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
crates/float/src/lib.rs (1)

359-392: Validate sig_figs_limit (reject 0; document practical upper bound)
Unvalidated limits can cause contract reverts or oversized outputs. Enforce >0 at the Rust API and (optionally) document a sane max (e.g., 68 for 224-bit coeff).

Apply:

-    pub fn format_with_limit(self, sig_figs_limit: u32) -> Result<String, FloatError> {
+    pub fn format_with_limit(self, sig_figs_limit: std::num::NonZeroU32) -> Result<String, FloatError> {
         let Float(a) = self;
         let calldata = DecimalFloat::formatCall {
             a,
-            sigFigsLimit: U256::from(sig_figs_limit),
+            sigFigsLimit: U256::from(sig_figs_limit.get()),
         }
         .abi_encode();

If you’d rather not change the signature, at minimum guard 0 and return a typed error.

crates/float/src/js_api.rs (2)

315-339: Add JS-side input validation for sig_figs_limit
Prevent 0 (and NaN/negatives coerced into u32) early; surface a clear error to callers.

Apply:

 #[wasm_export(js_name = "formatWithLimit")]
-    pub fn format_with_limit_js(&self, sig_figs_limit: u32) -> Result<String, FloatError> {
-        self.format_with_limit(sig_figs_limit)
-    }
+    pub fn format_with_limit_js(&self, sig_figs_limit: u32) -> Result<String, FloatError> {
+        let Some(limit) = std::num::NonZeroU32::new(sig_figs_limit) else {
+            return Err(FloatError::JsSysError("sig_figs_limit must be > 0".into()));
+        };
+        self.format_with_limit(limit)
+    }

If you keep the Rust API as u32, still perform this NonZero guard here and call the existing method.


117-145: Docs/types mismatch: use bigint (12345n), not string, in JS examples and return types
Current comments say “string” but the APIs use bigint. Fix examples to avoid confusing users.

Apply:

- /// * `value` - The fixed-point decimal value as a `string`.
+ /// * `value` - The fixed-point decimal value as a `bigint`.
@@
- /// const floatResult = Float.fromFixedDecimal("12345", 2);
+ /// const floatResult = Float.fromFixedDecimal(12345n, 2);
@@
- /// * `Ok(String)` - The resulting fixed-point decimal value as a string.
+ /// * `Ok(bigint)` - The resulting fixed-point decimal value as a bigint.
@@
- /// assert(result.value === "12345");
+ /// assert(result.value === 12345n);
@@
- /// * `value` - The fixed-point decimal value as a `string`.
+ /// * `value` - The fixed-point decimal value as a `bigint`.
@@
- /// const floatResult = Float.fromFixedDecimalLossy("12345", 2);
+ /// const floatResult = Float.fromFixedDecimalLossy(12345n, 2);
@@
- /// * `Ok(String)` - The resulting fixed-point decimal value as a string.
+ /// * `Ok(bigint)` - The resulting fixed-point decimal value as a bigint.
@@
- /// assert(result.value === "1234");
+ /// assert(result.value === 1234n);

I can sweep the rest of this file for similar doc nits if you want a follow-up PR.

Also applies to: 146-177, 178-206, 218-237

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f00888c and 216f5c3.

📒 Files selected for processing (3)
  • crates/float/src/js_api.rs (2 hunks)
  • crates/float/src/lib.rs (4 hunks)
  • test_js/float.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#59
File: crates/float/src/lib.rs:233-242
Timestamp: 2025-06-17T10:17:56.205Z
Learning: In the rainlanguage/rain.math.float repository, the maintainer 0xgleb prefers to handle documentation additions and improvements in separate issues rather than inline with feature PRs.
🧬 Code graph analysis (1)
crates/float/src/lib.rs (1)
crates/float/src/evm.rs (1)
  • execute_call (51-56)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-test)
🔇 Additional comments (4)
crates/float/src/lib.rs (3)

394-394: No action.


1198-1199: Updated expectations to fixed-point form make sense with the new default
These align with format() delegating to 18 sig figs.

Please confirm there’s no unintended switch to scientific notation at nearby magnitudes with the new formatter (e.g., 9999.9, 10000.1). If helpful I can add targeted property tests.

Also applies to: 1203-1204


338-357: Defaulting format() to 18 sig figs via delegation looks good
Thin wrapper is clean and keeps the default centralized. No lingering format18 or format18_js references remain.

crates/float/src/js_api.rs (1)

341-341: No action.

Comment thread test_js/float.test.ts
@0xgleb 0xgleb requested review from findolor and hardyjosh September 8, 2025 12:33
@0xgleb 0xgleb linked an issue Sep 8, 2025 that may be closed by this pull request
@thedavidmeister thedavidmeister merged commit 0984cbb into main Sep 8, 2025
10 checks passed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Sep 8, 2025

@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment:

S/M/L PR Classification Guidelines:

This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed.

Small (S)

Characteristics:

  • Simple bug fixes, typos, or minor refactoring
  • Single-purpose changes affecting 1-2 files
  • Documentation updates
  • Configuration tweaks
  • Changes that require minimal context to review

Review Effort: Would have taken 5-10 minutes

Examples:

  • Fix typo in variable name
  • Update README with new instructions
  • Adjust configuration values
  • Simple one-line bug fixes
  • Import statement cleanup

Medium (M)

Characteristics:

  • Feature additions or enhancements
  • Refactoring that touches multiple files but maintains existing behavior
  • Breaking changes with backward compatibility
  • Changes requiring some domain knowledge to review

Review Effort: Would have taken 15-30 minutes

Examples:

  • Add new feature or component
  • Refactor common utility functions
  • Update dependencies with minor breaking changes
  • Add new component with tests
  • Performance optimizations
  • More complex bug fixes

Large (L)

Characteristics:

  • Major feature implementations
  • Breaking changes or API redesigns
  • Complex refactoring across multiple modules
  • New architectural patterns or significant design changes
  • Changes requiring deep context and multiple review rounds

Review Effort: Would have taken 45+ minutes

Examples:

  • Complete new feature with frontend/backend changes
  • Protocol upgrades or breaking changes
  • Major architectural refactoring
  • Framework or technology upgrades

Additional Factors to Consider

When deciding between sizes, also consider:

  • Test coverage impact: More comprehensive test changes lean toward larger classification
  • Risk level: Changes to critical systems bump up a size category
  • Team familiarity: Novel patterns or technologies increase complexity

Notes:

  • the assessment must be for the totality of the PR, that means comparing the base branch to the last commit of the PR
  • the assessment output must be exactly one of: S, M or L (single-line comment) in format of: SIZE={S/M/L}
  • do not include any additional text, only the size classification
  • your assessment comment must not include tips or additional sections
  • do NOT tag me or anyone else on your comment

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 8, 2025

Oops, something went wrong! Please try again later. 🐰 💔

@0xgleb 0xgleb deleted the fix/formatter branch September 8, 2025 17:23
@coderabbitai coderabbitai Bot mentioned this pull request Oct 2, 2025
4 tasks
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.

remove rust version of float formatting

2 participants