format#26
Conversation
WalkthroughThe changes add new functionality for handling decimal floats. A new library, LibFormatDecimalFloat, has been created with functions to format decimal floats to strings, while LibParseDecimalFloat now includes a function to parse decimal floats from strings. New test cases in the respective test contracts cover formatting, round-trip conversion, and parsing, with several gas measurements updated. Additionally, a submodule for fixed-point math has been added to the repository along with an updated commit for that module. Changes
Possibly related PRs
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🔇 Additional comments (1)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
.gas-snapshot(2 hunks).gitmodules(1 hunks)lib/rain.math.fixedpoint(1 hunks)src/lib/format/LibFormatDecimalFloat.sol(1 hunks)src/lib/parse/LibParseDecimalFloat.sol(2 hunks)test/src/lib/format/LibFormatDecimalFloat.t.sol(1 hunks)test/src/lib/parse/LibParseDecimalFloat.t.sol(1 hunks)
🔇 Additional comments (15)
lib/rain.math.fixedpoint (1)
1-1: Submodule Commit Update VerificationThis update sets the submodule pointer to commit
6f8f7f8c79fd23b00aa5b9bda1171712e200023c. Please verify that this commit includes all the intended fixed-point math enhancements and that the submodule integration is functioning as expected in your overall build and test suite..gitmodules (1)
13-15: Integration of fixed-point math library.The addition of the rain.math.fixedpoint submodule is appropriate and aligns with the new functionality for formatting decimal floats that's being introduced.
src/lib/format/LibFormatDecimalFloat.sol (2)
5-7: Appropriate import structure.Good organization with separate imports for the internal decimal float library and the external fixed-point formatting library from the newly added submodule.
9-26: Clean implementation of decimal float formatting.The library provides a well-documented and maintainable approach to formatting decimal floats:
- Good documentation explaining the current implementation and future extensibility plans
- Smart reuse of the fixed-point library for string formatting
- Clean function overloading for convenience
The implementation correctly handles the conversion process by:
- Converting to a fixed decimal with 18 decimals precision using
toFixedDecimalLossless- Formatting that value as a string using the fixed-point library
This approach minimizes code duplication and leverages the capabilities of both libraries.
src/lib/parse/LibParseDecimalFloat.sol (2)
16-16: Appropriate import update.The addition of
Floatto the import statement is correct since it's now used as a return type in the new function.
144-154: Effective string-based decimal float parsing implementation.The new function complements the formatting functionality by providing a convenient way to parse decimal floats from strings. The implementation:
- Efficiently uses inline assembly to access the string's memory location
- Properly delegates to the existing parsing function for the actual parsing logic
- Correctly handles the return values to maintain the same error handling approach
The implementation is minimal and effective, creating a clean API that works well with the new formatting functions.
.gas-snapshot (2)
181-182: New formatting test cases with acceptable gas usage.The new test cases for the decimal float formatting functionality show reasonable gas consumption, with the round-trip test naturally using more gas due to the more complex operations involved.
188-212: Updated gas measurements for parsing tests.The small increases in gas usage for some of the parsing tests are reasonable and expected given the additional functionality. The new
testParseMemtest shows acceptable gas usage for the string-based parsing function.test/src/lib/parse/LibParseDecimalFloat.t.sol (4)
11-11: Import looks good.The import statement for the
Floatstruct is correctly added to support the new memory-based parsing functionality.
17-25: Well-implemented external wrapper function.This function provides a clear external interface to
LibParseDecimalFloat.parseDecimalFloatfor testing purposes, correctly handling the pointer unwrapping and data passing.
27-33: Good implementation of memory-based parsing wrapper.This function properly exposes the memory-based version of
LibParseDecimalFloat.parseDecimalFloatfor testing, with a clean interface returning both the error selector and the parsedFloatstruct.
35-48: Strong test comparison between stack and memory versions.This test function effectively verifies that both implementations produce consistent results by:
- Checking that error selectors match
- Verifying that parsed values (coefficient and exponent) are identical
- Properly handling error cases using try-catch and vm.expectRevert
The test ensures the robustness of both parsing implementations.
test/src/lib/format/LibFormatDecimalFloat.t.sol (3)
10-12: Clean contract and library usage.The contract definition and library usage declaration look good.
13-19: Well-implemented formatting wrapper functions.Both functions properly expose the
LibFormatDecimalFloat.toDecimalStringfunctionality for testing purposes - one using raw parameters and one using theFloatstruct.
21-30: Strong test comparison between formatting approaches.This test properly verifies that both the stack-based and memory-based approaches to formatting produce the same result, with appropriate error handling through try-catch.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
test/src/lib/format/LibFormatDecimalFloat.t.sol (1)
1-3: License inconsistency with other files persists.The license identifier
LicenseRef-DCL-1.0still differs from theCALlicense used in other files as noted in a previous review. This inconsistency should be standardized across the codebase.-// SPDX-License-Identifier: LicenseRef-DCL-1.0 +// SPDX-License-Identifier: CAL // SPDX-FileCopyrightText: Copyright (c) 2020 thedavidmeister pragma solidity =0.8.25;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
test/src/lib/format/LibFormatDecimalFloat.t.sol(1 hunks)
🔇 Additional comments (4)
test/src/lib/format/LibFormatDecimalFloat.t.sol (4)
13-15: LGTM! External wrapper function for testing stack parameters.This external function correctly allows for testing the stack version of the
toDecimalStringfunction.
17-19: LGTM! External wrapper function for testing memory parameters.This external function properly enables testing the memory version of the
toDecimalStringfunction.
21-30: Well-implemented test for format consistency across parameter types.The test appropriately verifies that the memory and stack versions of
toDecimalStringproduce identical results, with proper error propagation.
32-42: Well-structured round-trip test with improved documentation.The test effectively verifies that a value can be formatted to a string and then parsed back to the original value. The comments on lines 34-35 now clearly explain the rationale for the bound, addressing previous feedback.
Consider adding explicit edge case tests:
function testRoundTripEdgeCases() external { // Test zero testValueRoundTrip(0); // Test one testValueRoundTrip(1); // Test max bound testValueRoundTrip(type(uint256).max / 10); } function testValueRoundTrip(uint256 value) internal { Float memory float = LibDecimalFloat.fromFixedDecimalLosslessMem(value, 18); string memory formatted = LibFormatDecimalFloat.toDecimalString(float); (bytes4 errorCode, Float memory parsed) = LibParseDecimalFloat.parseDecimalFloat(formatted); assertEq(errorCode, 0, "Parse error"); assertTrue(float.eq(parsed), "Round trip failed"); }
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
….float into 2025-04-07-format
Motivation
Solution
Checks
By submitting this for review, I'm confirming I've done the following:
Summary by CodeRabbit
New Features
Tests