Skip to content

Add new constructor that receives already resolved currency to avoid …#161

Open
radykal-com wants to merge 2 commits into
Rhymond:masterfrom
stayforlong:reduce-currency-lookups
Open

Add new constructor that receives already resolved currency to avoid …#161
radykal-com wants to merge 2 commits into
Rhymond:masterfrom
stayforlong:reduce-currency-lookups

Conversation

@radykal-com

@radykal-com radykal-com commented Mar 9, 2026

Copy link
Copy Markdown

Hi @Rhymond,

This PR adds a new constructor that already receives the resolved currency.

Right now, all constructors have to allocate a temporary currency to just lookup if it exists (it also requires to scan the currency code and convert to uppercase if required). It becomes even worse when using the NewFromFloat that forces a math.Pow10 for each call.

With this new constructor, callers can implement currencies cache mechanisms to reduce this overhead.

Summary by Sourcery

Add a constructor that creates Money instances from an already resolved currency to avoid repeated currency lookups.

New Features:

  • Introduce NewWithCurrency constructor to create Money with a pre-resolved Currency.

Tests:

  • Add a unit test verifying Money created with NewWithCurrency is equal to one created with the existing constructor.

@sourcery-ai

sourcery-ai Bot commented Mar 9, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a new constructor that accepts an already-resolved Currency to avoid repeated currency lookup and formatting overhead, along with a unit test verifying behavior is equivalent to the existing constructor.

Class diagram for Money with new NewWithCurrency constructor

classDiagram
    class Money {
        -int64 amount
        -Currency* currency
        +New(amount int64, code string) Money*
        +NewWithCurrency(amount int64, currency Currency*) Money*
        +NewFromFloat(amount float64, code string) Money*
    }

    class Currency {
        <<struct>>
    }

    Money --> Currency : uses
Loading

File-Level Changes

Change Details Files
Introduce a constructor that builds Money from a pre-resolved Currency, bypassing the string-based lookup path.
  • Add NewWithCurrency(amount int64, currency *Currency) *Money that directly assigns the provided currency without validation or lookup
  • Document that the caller is responsible for providing a non-nil Currency and that the function skips currency resolution
money.go
Add a regression test ensuring the new constructor produces Money values equivalent to those from the existing string-based constructor.
  • Create TestNewWithCurrency to construct a Money with New, then construct another with NewWithCurrency using the first Money's currency
  • Verify that Equals returns true and no error between the two Money instances to confirm behavioral parity
money_test.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • Consider adding a defensive check (or at least a panic) if NewWithCurrency is called with a nil currency, so misuse is caught early instead of silently creating a Money with a nil currency pointer.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider adding a defensive check (or at least a panic) if `NewWithCurrency` is called with a nil `currency`, so misuse is caught early instead of silently creating a `Money` with a nil currency pointer.

## Individual Comments

### Comment 1
<location path="money_test.go" line_range="51" />
<code_context>
 	}
 }

+func TestNewWithCurrency(t *testing.T) {
+	m := New(1, EUR)
+
</code_context>
<issue_to_address>
**suggestion (testing):** Expand `TestNewWithCurrency` to assert that the same Currency instance is reused, not just value equality

Currently the test only checks value equality, which would still pass if `NewWithCurrency` re-resolved the currency instead of using the provided instance. Please also assert that `m.currency` and `om.currency` refer to the same `*Currency` (or equivalent invariant) so a future refactor that reintroduces a lookup will be caught by this test.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread money_test.go
}
}

func TestNewWithCurrency(t *testing.T) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): Expand TestNewWithCurrency to assert that the same Currency instance is reused, not just value equality

Currently the test only checks value equality, which would still pass if NewWithCurrency re-resolved the currency instead of using the provided instance. Please also assert that m.currency and om.currency refer to the same *Currency (or equivalent invariant) so a future refactor that reintroduces a lookup will be caught by this test.

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.

1 participant