Skip to content

Conversation

@0xgleb
Copy link
Contributor

@0xgleb 0xgleb commented Oct 15, 2025

fixes #158

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

    • Lossy fixed-decimal conversions now return a lossless boolean alongside values.
    • JS/WASM interface now returns structured result objects (value string + lossless flag) for to/from lossy fixed-decimal conversions.
  • Documentation

    • Examples and usage notes updated to show structured results and lossless indicators.
  • Tests

    • Added tests validating both lossy and lossless conversion paths and their result structures.

@0xgleb 0xgleb self-assigned this Oct 15, 2025
@0xgleb 0xgleb added the bug Something isn't working label Oct 15, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 15, 2025

Walkthrough

Core float conversions now return a (value, lossless) tuple; WASM/JS bindings expose structured result types (FromFixedDecimalLossyResult, ToFixedDecimalLossyResult) with serialization and getters; tests updated to assert both value and lossless flag.

Changes

Cohort / File(s) Summary
WASM JS API: lossy fixed-decimal structs & bindings
crates/float/src/js_api.rs
Added public structs FromFixedDecimalLossyResult and ToFixedDecimalLossyResult (serde/Tsify/wasm traits), getters, From<ToFixedDecimalLossyResult> for JsValue, new from_fixed_decimal_lossy_js(BigInt, u8) binding returning FromFixedDecimalLossyResult, and changed to_fixed_decimal_lossy_js(&self, u8) to return ToFixedDecimalLossyResult (value as string + lossless).
Core Float API: lossy flag propagation
crates/float/src/lib.rs
Changed signatures to return tuples with lossless flag: from_fixed_decimal_lossy(U256, u8) -> Result<(Self, bool), FloatError> and to_fixed_decimal_lossy(self, u8) -> Result<(U256, bool), FloatError>; updated internals, docs, and tests to propagate the lossless boolean.
JS tests for lossy/lossless
test_js/float.test.ts
Added/updated tests for fromFixedDecimalLossy and toFixedDecimalLossy to assert returned value strings and lossless booleans for both lossy and lossless scenarios.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor JS as JS Caller
  participant WASM as Float (wasm_bindgen)
  participant Core as Float Core

  JS->>WASM: toFixedDecimalLossy(decimals)
  WASM->>Core: to_fixed_decimal_lossy(self, decimals)
  Core-->>WASM: (U256 value, bool lossless)
  WASM-->>JS: ToFixedDecimalLossyResult { value: String, lossless }

  rect rgba(0,128,128,0.08)
    note right of WASM: New structured return includes lossless flag
  end
Loading
sequenceDiagram
  autonumber
  actor JS as JS Caller
  participant WASM as Float (wasm_bindgen)
  participant Core as Float Core

  JS->>WASM: fromFixedDecimalLossy(value: BigInt, decimals)
  WASM->>Core: from_fixed_decimal_lossy(U256(value), decimals)
  Core-->>WASM: (Float, bool lossless)
  WASM-->>JS: FromFixedDecimalLossyResult { float: Float, lossless }

  rect rgba(0,128,128,0.08)
    note right of WASM: New WASM entry returns Float plus lossless flag
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • hardyjosh
  • findolor

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR introduces a new FromFixedDecimalLossyResult struct, serialization support, and updates the from_fixed_decimal_lossy_js binding which are not part of issue #158’s requirement to only augment the toFixedDecimalLossy binding. Please isolate or justify the changes to from_fixed_decimal_lossy_js and the new serialization support or move them to a separate pull request so that this PR focuses solely on the toFixedDecimalLossy binding update.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “expose whether conversion was lossy or not” clearly summarizes the primary change of adding a lossiness flag to the conversion functions and is concise without extraneous details.
Linked Issues Check ✅ Passed This pull request directly updates the wasm binding for to_fixed_decimal_lossy_js to return a structured result including a boolean lossless flag as specified in issue #158, and the implementation and tests verify that the binding now returns both value and lossless indicator.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/tofixeddecimallossy-return

📜 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 9c77e6d and 52d40e2.

📒 Files selected for processing (1)
  • crates/float/src/js_api.rs (3 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#159
File: crates/float/src/js_api.rs:13-30
Timestamp: 2025-10-15T20:41:13.554Z
Learning: In the rain.math.float codebase, wasm_bindgen structs that are only returned to TypeScript/JavaScript (like `FromFixedDecimalLossyResult`) don't need Rust trait derives (Debug, Clone, PartialEq, Serialize, Deserialize, Tsify) beyond what's required for JS interop. Only add these derives when the struct is used for Rust-side operations like serialization, debugging, or testing.
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#115
File: test/src/lib/LibDecimalFloat.decimal.t.sol:122-126
Timestamp: 2025-08-29T14:54:24.240Z
Learning: In test/src/lib/LibDecimalFloat.decimal.t.sol, the fromFixedDecimalLossy function converts uint256(type(int256).max) losslessly because the boundary check is `value > uint256(type(int256).max)`, not `>=`. Values exactly equal to type(int256).max still take the lossless conversion path.
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#115
File: test/src/lib/LibDecimalFloat.decimal.t.sol:122-126
Timestamp: 2025-08-29T14:54:24.240Z
Learning: In test/src/lib/LibDecimalFloat.decimal.t.sol, the fromFixedDecimalLossy function converts uint256(type(int256).max) losslessly because the boundary check is `value > uint256(type(int256).max)`, not `>=`. Values exactly equal to type(int256).max still take the lossless conversion path.
📚 Learning: 2025-10-15T20:41:13.554Z
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#159
File: crates/float/src/js_api.rs:13-30
Timestamp: 2025-10-15T20:41:13.554Z
Learning: In the rain.math.float codebase, wasm_bindgen structs that are only returned to TypeScript/JavaScript (like `FromFixedDecimalLossyResult`) don't need Rust trait derives (Debug, Clone, PartialEq, Serialize, Deserialize, Tsify) beyond what's required for JS interop. Only add these derives when the struct is used for Rust-side operations like serialization, debugging, or testing.

Applied to files:

  • crates/float/src/js_api.rs
📚 Learning: 2025-06-18T09:10:41.740Z
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#57
File: crates/float/src/lib.rs:316-328
Timestamp: 2025-06-18T09:10:41.740Z
Learning: In the rain.math.float codebase, the user prefers implementing standard Rust traits (like Neg) rather than creating redundant public methods when the trait already provides the needed functionality. Float implements Copy, so reference usage with operators is not a concern.

Applied to files:

  • crates/float/src/js_api.rs
📚 Learning: 2025-07-03T11:20:50.456Z
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#70
File: crates/float/src/evm.rs:38-43
Timestamp: 2025-07-03T11:20:50.456Z
Learning: In the rainlanguage/rain.math.float codebase, the user 0xgleb prefers not to add explanatory comments for well-established Rust idioms like the double `?` pattern, as these are self-explanatory to experienced Rust developers and don't need over-commenting.

Applied to files:

  • crates/float/src/js_api.rs
🧬 Code graph analysis (1)
crates/float/src/js_api.rs (2)
crates/float/src/error.rs (3)
  • from (79-84)
  • from (88-90)
  • from (94-96)
crates/float/src/lib.rs (3)
  • from (1243-1245)
  • from (1249-1251)
  • from_fixed_decimal_lossy (153-161)
⏰ 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). (9)
  • GitHub Check: git-clean
  • GitHub Check: rainix (macos-latest, rainix-sol-legal)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-test)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-static)
  • GitHub Check: rainix (ubuntu-latest, test-wasm-build)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-legal)
  • GitHub Check: rainix (macos-latest, rainix-rs-test)
  • GitHub Check: rainix (ubuntu-latest, rainix-rs-test)
  • GitHub Check: rainix (ubuntu-latest, rainix-rs-static)
🔇 Additional comments (5)
crates/float/src/js_api.rs (5)

3-11: LGTM! Imports support the new result types.

The added imports for serde serialization and wasm_bindgen_utils are appropriate for exposing structured result types to TypeScript/JavaScript.


13-30: LGTM! Result struct correctly exposes both values.

The FromFixedDecimalLossyResult struct appropriately encapsulates the float value and lossless flag with proper getters for JavaScript interop. The minimal trait derives are intentional for JS-only structs.


32-37: LGTM! Result struct properly configured for serialization.

The ToFixedDecimalLossyResult struct has appropriate derives and public fields for the wasm_export serialization path, correctly exposing both the value and lossless flag to JavaScript.


91-142: Excellent implementation with comprehensive documentation!

The from_fixed_decimal_lossy_js function correctly implements the required functionality:

  • Properly converts from BigInt through U256 to Float
  • Captures and returns both the converted value and lossless flag
  • Provides thorough documentation with clear examples
  • Handles errors appropriately

This addresses the PR objective of exposing lossiness information from the conversion.


261-280: Implementation correctly addresses PR objectives.

The to_fixed_decimal_lossy_js function properly returns both the converted value and the lossless flag in a ToFixedDecimalLossyResult, which directly addresses issue #158. The logic correctly unpacks the tuple from to_fixed_decimal_lossy and structures it for JavaScript consumption.

Note: A previous review suggested expanding the documentation to match the comprehensive style of from_fixed_decimal_lossy_js, but this remains unaddressed. The current minimal documentation is functional but inconsistent with the project's documentation standards shown elsewhere in this file.


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

@0xgleb 0xgleb requested review from findolor and hardyjosh October 15, 2025 18:58
Copy link
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: 3

Caution

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

⚠️ Outside diff range comments (2)
crates/float/src/js_api.rs (1)

174-176: Doc nit: parameter type is bigint, not string

Update doc to match the JS API.

Apply this diff:

-    /// * `value` - The fixed-point decimal value as a `string`.
+    /// * `value` - The fixed-point decimal value as a `bigint`.
crates/float/src/lib.rs (1)

2005-2032: Robustness tests: from_fixed_decimal_lossy

Good coverage for lossless cases and an explicit lossy U256::MAX case. Consider adding the int256::max boundary case as explicitly lossless (matches on-chain logic).

Based on learnings

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4473754 and 2ccb96e.

📒 Files selected for processing (3)
  • crates/float/src/js_api.rs (3 hunks)
  • crates/float/src/lib.rs (7 hunks)
  • test_js/float.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-29T14:54:24.240Z
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#115
File: test/src/lib/LibDecimalFloat.decimal.t.sol:122-126
Timestamp: 2025-08-29T14:54:24.240Z
Learning: In test/src/lib/LibDecimalFloat.decimal.t.sol, the fromFixedDecimalLossy function converts uint256(type(int256).max) losslessly because the boundary check is `value > uint256(type(int256).max)`, not `>=`. Values exactly equal to type(int256).max still take the lossless conversion path.

Applied to files:

  • test_js/float.test.ts
  • crates/float/src/lib.rs
🧬 Code graph analysis (3)
test_js/float.test.ts (1)
crates/float/src/js_api.rs (1)
  • float (19-21)
crates/float/src/lib.rs (2)
crates/float/src/evm.rs (1)
  • execute_call (51-56)
crates/float/src/js_api.rs (3)
  • from (37-39)
  • float (19-21)
  • lossless (24-26)
crates/float/src/js_api.rs (1)
crates/float/src/lib.rs (3)
  • from (1243-1245)
  • from (1249-1251)
  • from_fixed_decimal_lossy (153-161)
⏰ 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). (6)
  • GitHub Check: rainix (ubuntu-latest, rainix-rs-static)
  • GitHub Check: rainix (ubuntu-latest, test-wasm-build)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-test)
  • GitHub Check: rainix (macos-latest, rainix-sol-legal)
  • GitHub Check: rainix (ubuntu-latest, rainix-rs-test)
  • GitHub Check: rainix (macos-latest, rainix-rs-test)
🔇 Additional comments (8)
crates/float/src/js_api.rs (2)

10-27: Good JS-friendly result wrapper for fromFixedDecimalLossy

Shape and getters are appropriate for wasm_bindgen. LGTM.


241-249: toFixedDecimalLossy now returns structured result (value + lossless)

Return shape matches the PR objective and tests. LGTM.

Please confirm downstream TypeScript definitions are regenerated so "ToFixedDecimalLossyResult" appears in the emitted d.ts.

test_js/float.test.ts (2)

44-49: Covers fromFixedDecimalLossy lossless path

Assertions read well and exercise the new API surface. LGTM.


50-56: Covers toFixedDecimalLossy lossy and lossless paths

Good checks for both value and lossless flag. LGTM.

Add a boundary test for fromFixedDecimalLossy at the exact threshold known to be lossless (uint256(int256::max)), to guard regression on the contract boundary check. Based on learnings.

Proposed test snippet:

it('fromFixedDecimalLossy boundary is lossless at int256::max', () => {
  // int256::max = 2**255 - 1
  const int256Max = (1n << 255n) - 1n;
  const { float, lossless } = Float.fromFixedDecimalLossy(int256Max, 0);
  expect(lossless).toBe(true);
  // sanity: round-trip lossless toFixedDecimalLossy(0) should give back the same decimal string
  const r = float.toFixedDecimalLossy(0);
  expect(r.error).toBeUndefined();
  expect(r.value!.value).toBe(int256Max.toString());
  expect(r.value!.lossless).toBe(true);
});

Based on learnings

Also applies to: 58-64

crates/float/src/lib.rs (4)

153-161: Core API now returns (Float, bool) for from_fixed_decimal_lossy

Decoding tuple and propagation look correct. LGTM.


188-197: Core API now returns (U256, bool) for to_fixed_decimal_lossy

Tuple wiring to decoded fields looks correct. LGTM.


2036-2085: Robustness tests: to_fixed_decimal_lossy

Covers both lossy and lossless examples with clear expectations. LGTM.


2089-2112: Property test asserts lossless on from_fixed_decimal_lossy and conditional lossiness on to_fixed_decimal_lossy

Nice property-based coverage; conditions match spec. LGTM.

Comment on lines 99 to 112
#[wasm_bindgen(js_name = "fromFixedDecimalLossy")]
pub fn from_fixed_decimal_lossy_wasm(
value: BigInt,
decimals: u8,
) -> Result<FromFixedDecimalLossyResult, JsValue> {
let value_str: String = value
.to_string(10)
.map(|s| s.into())
.map_err(|e| JsValue::from(&e))?;
let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
let (float, lossless) = Float::from_fixed_decimal_lossy(val, decimals)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(FromFixedDecimalLossyResult { float, lossless })
}
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 15, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Simplify BigInt → String conversion and error mapping

Current map/map_err is redundant; use the same concise pattern as elsewhere.

Apply this diff:

-        let value_str: String = value
-            .to_string(10)
-            .map(|s| s.into())
-            .map_err(|e| JsValue::from(&e))?;
+        let value_str: String = value.to_string(10)?.into();
📝 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
#[wasm_bindgen(js_name = "fromFixedDecimalLossy")]
pub fn from_fixed_decimal_lossy_wasm(
value: BigInt,
decimals: u8,
) -> Result<FromFixedDecimalLossyResult, JsValue> {
let value_str: String = value
.to_string(10)
.map(|s| s.into())
.map_err(|e| JsValue::from(&e))?;
let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
let (float, lossless) = Float::from_fixed_decimal_lossy(val, decimals)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(FromFixedDecimalLossyResult { float, lossless })
}
#[wasm_bindgen(js_name = "fromFixedDecimalLossy")]
pub fn from_fixed_decimal_lossy_wasm(
value: BigInt,
decimals: u8,
) -> Result<FromFixedDecimalLossyResult, JsValue> {
let value_str: String = value.to_string(10)?.into();
let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
let (float, lossless) = Float::from_fixed_decimal_lossy(val, decimals)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(FromFixedDecimalLossyResult { float, lossless })
}
🤖 Prompt for AI Agents
In crates/float/src/js_api.rs around lines 99 to 112, streamline the
BigInt→String conversion by removing the redundant map call and mapping directly
on to_string; replace the current value.to_string(10).map(|s|
s.into()).map_err(|e| JsValue::from(&e))? with a single call that returns the
String and maps the error once (e.g. let value_str =
value.to_string(10).map_err(|e| JsValue::from(&e))?); keep the subsequent
U256::from_str and error mappings unchanged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Copy link
Contributor

Choose a reason for hiding this comment

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

@0xgleb, thank you for applying the fix! The simplified conversion is much cleaner. 🎉

    /)_/)
   (^.^)  
   />💻

Copy link
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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb4cba5 and 9c77e6d.

📒 Files selected for processing (1)
  • crates/float/src/js_api.rs (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#115
File: test/src/lib/LibDecimalFloat.decimal.t.sol:122-126
Timestamp: 2025-08-29T14:54:24.240Z
Learning: In test/src/lib/LibDecimalFloat.decimal.t.sol, the fromFixedDecimalLossy function converts uint256(type(int256).max) losslessly because the boundary check is `value > uint256(type(int256).max)`, not `>=`. Values exactly equal to type(int256).max still take the lossless conversion path.
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#115
File: test/src/lib/LibDecimalFloat.decimal.t.sol:122-126
Timestamp: 2025-08-29T14:54:24.240Z
Learning: In test/src/lib/LibDecimalFloat.decimal.t.sol, the fromFixedDecimalLossy function converts uint256(type(int256).max) losslessly because the boundary check is `value > uint256(type(int256).max)`, not `>=`. Values exactly equal to type(int256).max still take the lossless conversion path.
Learnt from: thedavidmeister
PR: rainlanguage/rain.math.float#111
File: test/src/lib/LibDecimalFloat.div.t.sol:48-51
Timestamp: 2025-08-26T16:50:11.113Z
Learning: In LibDecimalFloat, packLossless internally asserts that the packing operation is lossless, so there's no need to manually check the lossless flag when using packLossless instead of packLossy.
🧬 Code graph analysis (1)
crates/float/src/js_api.rs (1)
crates/float/src/lib.rs (3)
  • from (1243-1245)
  • from (1249-1251)
  • from_fixed_decimal_lossy (153-161)
⏰ 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). (9)
  • GitHub Check: git-clean
  • GitHub Check: rainix (ubuntu-latest, rainix-rs-test)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-legal)
  • GitHub Check: rainix (ubuntu-latest, rainix-rs-static)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-static)
  • GitHub Check: rainix (ubuntu-latest, test-wasm-build)
  • GitHub Check: rainix (macos-latest, rainix-rs-test)
  • GitHub Check: rainix (macos-latest, rainix-sol-legal)
  • GitHub Check: rainix (ubuntu-latest, rainix-sol-test)
🔇 Additional comments (2)
crates/float/src/js_api.rs (2)

32-37: LGTM!

The struct is well-defined with appropriate trait derives and macro usage for WASM/JS interop.


235-244: LGTM!

The function correctly unpacks the tuple result from to_fixed_decimal_lossy, converts the U256 value to a string, and wraps both the value and lossless flag in the result struct. The implementation aligns with the PR objective to expose lossiness information.

Comment on lines +13 to +30
#[wasm_bindgen]
pub struct FromFixedDecimalLossyResult {
float: Float,
lossless: bool,
}

#[wasm_bindgen]
impl FromFixedDecimalLossyResult {
#[wasm_bindgen(getter)]
pub fn float(&self) -> Float {
self.float
}

#[wasm_bindgen(getter)]
pub fn lossless(&self) -> bool {
self.lossless
}
}
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 15, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding trait derives for consistency and ergonomics.

ToFixedDecimalLossyResult (lines 32-37) has derives for Serialize, Deserialize, Debug, Clone, PartialEq, and Tsify, plus impl_wasm_traits!. FromFixedDecimalLossyResult lacks these traits, which may limit debugging, testing, and serialization capabilities.

If the Float type supports these traits, apply this diff to add them:

+#[derive(Debug, Clone, PartialEq)]
 #[wasm_bindgen]
 pub struct FromFixedDecimalLossyResult {
     float: Float,
     lossless: bool,
 }

If serialization is needed for JS interop consistency, consider also adding Serialize, Deserialize, and Tsify (assuming Float supports them).

📝 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
#[wasm_bindgen]
pub struct FromFixedDecimalLossyResult {
float: Float,
lossless: bool,
}
#[wasm_bindgen]
impl FromFixedDecimalLossyResult {
#[wasm_bindgen(getter)]
pub fn float(&self) -> Float {
self.float
}
#[wasm_bindgen(getter)]
pub fn lossless(&self) -> bool {
self.lossless
}
}
#[derive(Debug, Clone, PartialEq)]
#[wasm_bindgen]
pub struct FromFixedDecimalLossyResult {
float: Float,
lossless: bool,
}
#[wasm_bindgen]
impl FromFixedDecimalLossyResult {
#[wasm_bindgen(getter)]
pub fn float(&self) -> Float {
self.float
}
#[wasm_bindgen(getter)]
pub fn lossless(&self) -> bool {
self.lossless
}
}
🤖 Prompt for AI Agents
In crates/float/src/js_api.rs around lines 13 to 30, FromFixedDecimalLossyResult
is missing the same trait derives and wasm helper impls as
ToFixedDecimalLossyResult; add derives (e.g., Serialize, Deserialize, Debug,
Clone, PartialEq, Tsify) and call impl_wasm_traits! for
FromFixedDecimalLossyResult (only if the contained Float type supports those
traits), ensuring the struct keeps #[wasm_bindgen] for JS export and that any
feature flags/imports needed for Serialize/Deserialize/Tsify are enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not needed, only gonna be used from ts/js

Copy link
Contributor

Choose a reason for hiding this comment

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

@0xgleb, understood! Since FromFixedDecimalLossyResult is only consumed by TypeScript/JavaScript and not used for Rust-side operations, the additional trait derives aren't necessary.


✏️ Learnings added
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#159
File: crates/float/src/js_api.rs:13-30
Timestamp: 2025-10-15T20:41:13.554Z
Learning: In the rain.math.float codebase, wasm_bindgen structs that are only returned to TypeScript/JavaScript (like `FromFixedDecimalLossyResult`) don't need Rust trait derives (Debug, Clone, PartialEq, Serialize, Deserialize, Tsify) beyond what's required for JS interop. Only add these derives when the struct is used for Rust-side operations like serialization, debugging, or testing.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: 0xgleb
PR: rainlanguage/rain.math.float#57
File: crates/float/src/lib.rs:316-328
Timestamp: 2025-06-18T09:10:41.740Z
Learning: In the rain.math.float codebase, the user prefers implementing standard Rust traits (like Neg) rather than creating redundant public methods when the trait already provides the needed functionality. Float implements Copy, so reference usage with operators is not a concern.

Comment on lines +101 to +102
let value_str: String = value.to_string(10).map_err(|e| JsValue::from(&e))?.into();
let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 15, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Standardize error conversion patterns.

Lines 101 and 102 use different error conversion approaches:

  • Line 101: JsValue::from(&e)
  • Line 102: JsValue::from_str(&e.to_string())

For consistency with similar functions (e.g., from_fixed_decimal_js at line 189), use a uniform pattern:

-        let value_str: String = value.to_string(10).map_err(|e| JsValue::from(&e))?.into();
+        let value_str: String = value.to_string(10)?.into();
         let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
📝 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
let value_str: String = value.to_string(10).map_err(|e| JsValue::from(&e))?.into();
let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
let value_str: String = value.to_string(10)?.into();
let val = U256::from_str(&value_str).map_err(|e| JsValue::from_str(&e.to_string()))?;
🤖 Prompt for AI Agents
In crates/float/src/js_api.rs around lines 101 to 102, the error conversions are
inconsistent: change the map_err on line 101 to use
JsValue::from_str(&e.to_string()) so both lines use the same pattern
(map_err(|e| JsValue::from_str(&e.to_string()))?), matching the style used in
from_fixed_decimal_js at line 189; ensure both error mappings return a
JsValue::from_str of the error's to_string().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not needed

Copy link
Contributor

Choose a reason for hiding this comment

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

@0xgleb, understood. I'll leave the error conversion as is.

@0xgleb 0xgleb merged commit 9d12ba7 into main Oct 18, 2025
10 checks passed
@0xgleb 0xgleb deleted the fix/tofixeddecimallossy-return branch October 18, 2025 18:56
@github-actions
Copy link

@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
Contributor

coderabbitai bot commented Oct 18, 2025

Tip

For best results, initiate chat on the files or code changes.

SIZE=M

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

toFixedDecimalLossy wasm binding does not return bool for loseless flag

4 participants