money

package module
v0.0.0-...-fe64c97 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

README

go-ruby-money/money

money — go-ruby-money

Docs License Go Coverage

A pure-Go (no cgo) reimplementation of the Ruby money gem (RubyMoney) — the integer-cents Money value object, its arithmetic and penny-safe allocate / split, the embedded ISO 4217 currency table, byte-faithful format, and the variable-exchange bank. It reproduces the gem's behaviour without any Ruby runtime, validated differentially against the money gem on Ruby ≥ 4.0.

It is the money backend for go-embedded-ruby, but is a standalone, reusable module — a sibling of go-ruby-yaml, go-ruby-regexp and go-ruby-erb.

What it is — and isn't. A Money is (fractional int64 minor units, Currency, Bank). Arithmetic, the allocate/split remainder distribution, the currency data, and formatting are fully deterministic and need no interpreter, so they live here as pure Go. The exchange-rate source is a host seam: a VariableExchange bank holds rates the host injects (AddRate), and this library implements the exchange math; a SingleCurrency bank refuses every conversion.

Features

Faithful port of the gem, validated against the money gem on every platform that has it:

  • Integer-cents value modelNew(fractional, currency), .Fractional() / .Cents(), .Amount() (exact decimal *big.Rat), .Currency(), .Bank(), and FromAmount (decimal → cents).
  • ArithmeticAdd / Sub (auto-exchanging a differing currency), Mul / Div by a scalar, DivMoney (ratio), DivMod, Modulo / %, Remainder, Neg, Abs, Cmp, Eql — with the gem's rounding on non-integer results.
  • Penny-safe distributionAllocate([weights]) and Split(n) reproduce the gem's exact remainder round-robin (no lost pennies), including the integer floored-division semantics for negative amounts.
  • ISO 4217 currency table — the gem's currency_iso.json (+ non-ISO and backwards-compatible additions) is go:embedded: MustCurrency("USD"), FindCurrency, FindCurrencyByISONumeric, RegisterCurrency, AllCurrencies; each carries symbol, subunit, subunit_to_unit, decimal mark, thousands separator, ISO numeric, exponent, and more.
  • FormattingFormat(Options{…}): symbol / no-symbol / fixed symbol, decimal mark, thousands separator, symbol position, sign / sign-before-symbol / sign-positive, no_cents / no_cents_if_whole, drop_trailing_zeros, display_free, with_currency, disambiguate, custom %u/%n templates, and South-Asian (lakh/crore) grouping — byte-faithful to the gem.
  • Exchange (host seam)VariableExchange with injected rates and the gem's subunit-aware conversion math; SingleCurrency refuses exchanges; DefaultBank / SetDefaultBank / AddRate mirror the class-level API.

CGO-free, dependency-free, 100% test coverage, gofmt + go vet clean, and green across the six 64-bit Go targets (amd64, arm64, riscv64, loong64, ppc64le, s390x).

Install

go get github.com/go-ruby-money/money

Usage

package main

import (
	"fmt"
	"math/big"

	"github.com/go-ruby-money/money"
)

func main() {
	usd := money.MustCurrency("USD")

	price := money.New(123456, usd) // 123456 cents
	fmt.Println(price.Format(money.Options{})) // $1,234.56

	// Penny-safe split — no lost cents.
	for _, part := range money.New(100, usd).Allocate([]int64{1, 1, 1}) {
		fmt.Print(part.Fractional(), " ") // 34 33 33
	}
	fmt.Println()

	// Arithmetic.
	total, _ := price.Add(money.New(44, usd))
	fmt.Println(total.Format(money.Options{})) // $1,235.00

	// Exchange — rates are a host seam.
	bank := money.NewVariableExchange()
	bank.AddRate(usd, money.MustCurrency("EUR"), big.NewRat(9, 10))
	eur, _ := bank.ExchangeWith(money.NewWithBank(1000, usd, bank), money.MustCurrency("EUR"))
	fmt.Println(eur.Fractional()) // 900
}

Value model

A host such as go-embedded-ruby maps its own Money objects to and from this shape:

Ruby Go
Money.new(100, "USD") money.New(100, money.MustCurrency("USD"))
m.fractional / m.cents m.Fractional() (int64)
m.amount / m.to_d m.Amount() (*big.Rat)
m.currency m.Currency() (*money.Currency)
Money::Currency.new("USD") money.MustCurrency("USD") / money.NewCurrency
Money.default_bank money.DefaultBank() / money.SetDefaultBank
bank.add_rate(...) bank.AddRate(...)

Tests & coverage

The suite pairs deterministic, ruby-free golden vectors (which alone hold coverage at 100%, so the qemu cross-arch and Windows lanes pass the gate) with a differential oracle against the real money gem: format across currencies+options, arithmetic, allocate/split remainder distribution, currency lookups, and the exchange math are all compared to the gem's output. The oracle version-gates RUBY_VERSION >= "4.0", $stdout.binmodes its scripts, and skips itself where ruby / the gem is absent.

COVERPKG=$(go list ./... | paste -sd, -)
go test -race -coverpkg="$COVERPKG" -coverprofile=cover.out ./...
go tool cover -func=cover.out | tail -1   # 100.0%

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-money/money authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

Documentation

Overview

Package money is a pure-Go (CGO-free), MRI-faithful reimplementation of the Ruby `money` gem (RubyMoney). It models an amount of a specific currency as an integer number of minor units (cents) plus a *Currency, and reproduces the gem's arithmetic, allocate/split penny distribution, ISO 4217 currency table, formatting, and variable-exchange bank — byte-for-byte where the gem is deterministic — without any Ruby runtime.

The rate source for currency exchange is a host seam: a *VariableExchange bank holds rates injected by the host (Money.add_rate / bank.add_rate), and the exchange math is implemented here. A *SingleCurrency bank refuses any exchange.

Value model

A Money value is (fractional int64 minor units, currency, bank). A host such as go-embedded-ruby maps its own Money objects to and from this shape:

Ruby                       Go
----                       --
Money.new(100, "USD")      money.New(100, money.MustCurrency("USD"))
m.fractional / m.cents     m.Fractional() (int64)
m.amount / m.to_d          m.Amount() (*big.Rat)
m.currency                 m.Currency() (*Currency)
Money::Currency.new("USD") money.Currency(...) / money.MustCurrency(...)

Index

Constants

This section is empty.

Variables

View Source
var DefaultRoundingMode = HalfUp

DefaultRoundingMode is the process-wide rounding mode used when converting a non-integer minor-unit value to an integer (Money.rounding_mode). It defaults to HalfUp, as in the gem.

Functions

func AddRate

func AddRate(from, to *Currency, rate *big.Rat) *big.Rat

AddRate registers a rate on the default bank (which must be a *VariableExchange) and returns it, the analogue of Money.add_rate. It panics if the default bank does not support rates.

func DisallowCurrencyConversion

func DisallowCurrencyConversion()

DisallowCurrencyConversion sets the default bank to a SingleCurrency bank, the analogue of Money.disallow_currency_conversion!.

func RegisterCurrency

func RegisterCurrency(c Currency)

RegisterCurrency adds or replaces a currency keyed by its (lowercased) ISO code, matching Money::Currency.register. A caller that mutates the returned table after registration does not affect the registry.

func SetDefaultBank

func SetDefaultBank(b Bank)

SetDefaultBank sets the process-wide default bank, the analogue of Money.default_bank=.

func UnregisterCurrency

func UnregisterCurrency(id string) bool

UnregisterCurrency removes a currency by id / code and reports whether it existed, matching Money::Currency.unregister.

Types

type Bank

type Bank interface {
	// ExchangeWith converts from into to, or returns an error when no rate is
	// known (or exchange is disallowed).
	ExchangeWith(from *Money, to *Currency) (*Money, error)
}

Bank is the currency-exchange seam. The rate source is supplied by the host — VariableExchange holds rates injected via AddRate, and SingleCurrency refuses every exchange. A Bank converts a Money into another currency, the analogue of Money::Bank::Base#exchange_with.

func DefaultBank

func DefaultBank() Bank

DefaultBank returns the process-wide default bank, the analogue of Money.default_bank. It defaults to an empty VariableExchange.

type Currency

type Currency struct {
	// ID is the lowercase identifier (e.g. "usd"); it is the canonical key.
	ID string
	// Priority orders the currency list (lower sorts first).
	Priority int
	// ISOCode is the upper-case 3-letter ISO 4217 code (e.g. "USD").
	ISOCode string
	// ISONumeric is the 3-digit ISO 4217 numeric code, zero-padded (e.g. "840").
	ISONumeric string
	// Name is the currency's human name (e.g. "United States Dollar").
	Name string
	// Symbol is the currency symbol (e.g. "$"); may be empty.
	Symbol string
	// DisambiguateSymbol is an alternative symbol used when Symbol is ambiguous
	// (e.g. "US$" / "C$").
	DisambiguateSymbol string
	// HTMLEntity is the HTML entity for the symbol (e.g. "$", "¥").
	HTMLEntity string
	// AlternateSymbols are other symbols in use for the currency.
	AlternateSymbols []string
	// Subunit is the name of the fractional unit (e.g. "Cent"); may be empty.
	Subunit string
	// SubunitToUnit is the proportion between unit and subunit (e.g. 100).
	SubunitToUnit int64
	// DecimalMark separates the whole part from the subunit (e.g. ".").
	DecimalMark string
	// ThousandsSeparator groups the whole part (e.g. ",").
	ThousandsSeparator string
	// SymbolFirst reports whether the symbol precedes the amount.
	SymbolFirst bool
	// SmallestDenomination is the smallest cash amount, in subunits (e.g. 1, 5).
	SmallestDenomination int64
	// Format is an optional "%u%n"-style template overriding the default layout.
	Format string
}

Currency represents a specific currency unit — the Go analogue of Money::Currency. It is loaded from the embedded ISO 4217 table (with the gem's non-ISO and backwards-compatible additions merged in) and is immutable once registered. Look one up with Currency / MustCurrency / FindCurrency / FindCurrencyByISONumeric, or add your own with RegisterCurrency.

func AllCurrencies

func AllCurrencies() []*Currency

AllCurrencies returns every registered currency sorted by priority then id, matching Money::Currency.all / .each iteration order.

func FindCurrency

func FindCurrency(id string) *Currency

FindCurrency looks up a currency by id / code, returning nil (no error) when it is unknown — the analogue of Money::Currency.find.

func FindCurrencyByISONumeric

func FindCurrencyByISONumeric(num string) *Currency

FindCurrencyByISONumeric looks a currency up by its ISO 4217 numeric code (e.g. 840 or "840"), zero-padding to three digits first, matching Money::Currency.find_by_iso_numeric. It returns nil when unknown.

func MustCurrency

func MustCurrency(id string) *Currency

MustCurrency is like NewCurrency but panics on an unknown id; it is convenient for currencies known to exist at call sites (e.g. MustCurrency("USD")).

func NewCurrency

func NewCurrency(id string) (*Currency, error)

NewCurrency looks up a currency by its id or ISO code (case-insensitive), the analogue of Money::Currency.new. It returns an *UnknownCurrencyError for an unknown id.

func WrapCurrency

func WrapCurrency(id string) *Currency

WrapCurrency returns c unchanged when non-nil, else looks id up. It mirrors Money::Currency.wrap for the string case and is used internally to accept either a *Currency or a code where the gem does.

func (*Currency) CentsBased

func (c *Currency) CentsBased() bool

CentsBased reports whether the subunit is hundredths, matching Currency#cents_based?.

func (*Currency) Code

func (c *Currency) Code() string

Code returns the symbol, or the ISO code when there is no symbol, matching Currency#code.

func (*Currency) DecimalPlaces

func (c *Currency) DecimalPlaces() int

DecimalPlaces is an alias for Currency.Exponent, matching the gem's alias.

func (*Currency) Equal

func (c *Currency) Equal(other *Currency) bool

Equal reports whether two currencies denote the same currency (same id), matching Currency#==. A nil receiver equals only a nil other.

func (*Currency) Exponent

func (c *Currency) Exponent() int

Exponent returns the base-10 exponent relating subunit to unit, i.e. round(log10(subunit_to_unit)), matching Currency#exponent / #decimal_places.

func (*Currency) ISO

func (c *Currency) ISO() bool

ISO reports whether the currency carries an ISO 4217 numeric code, matching Currency#iso?.

func (*Currency) String

func (c *Currency) String() string

String returns the upper-case ISO id (e.g. "USD"), matching Currency#to_s.

func (*Currency) SymbolOrDefault

func (c *Currency) SymbolOrDefault() string

SymbolOrDefault returns the currency symbol, or the generic "¤" placeholder when the currency has none — the value Money#symbol uses.

type DifferentCurrencyError

type DifferentCurrencyError struct{ From, To string }

DifferentCurrencyError is returned by SingleCurrency when any exchange is attempted, mirroring Money::Bank::DifferentCurrencyError.

func (*DifferentCurrencyError) Error

func (e *DifferentCurrencyError) Error() string

type Money

type Money struct {
	// contains filtered or unexported fields
}

Money is an immutable amount of a specific currency, held as an integer number of minor units (cents) plus a *Currency and a Bank. It is the Go analogue of the gem's Money value object.

func FromAmount

func FromAmount(amount *big.Rat, currency *Currency) *Money

FromAmount returns a Money for a decimal amount in the given currency, scaling by the currency's subunit_to_unit and rounding to an integer with the default rounding mode — the analogue of Money.from_amount(amount, currency). The amount is given as a *big.Rat so callers keep exact decimals.

func New

func New(fractional int64, currency *Currency) *Money

New returns a Money of fractional minor units (cents) in the given currency, using the DefaultBank — the analogue of Money.new(fractional, currency).

func NewWithBank

func NewWithBank(fractional int64, currency *Currency, bank Bank) *Money

NewWithBank is like New but binds an explicit bank for currency exchange.

func (*Money) Abs

func (m *Money) Abs() *Money

Abs returns the absolute value, matching Money#abs.

func (*Money) Add

func (m *Money) Add(other *Money) (*Money, error)

Add returns the sum of m and other. When other has a different currency it is first exchanged to m's currency, matching Money#+. It returns an error only when that exchange fails (no rate / disallowed).

func (*Money) Allocate

func (m *Money) Allocate(parts []int64) []*Money

Allocate distributes m into parts proportional to the given weights, without losing pennies — the analogue of Money#allocate(parts). The left-over minor units are handed out so that earlier parts receive them first, exactly as the gem does. Passing all-zero weights splits evenly. It panics on an empty parts slice (matching the gem's ArgumentError).

func (*Money) Amount

func (m *Money) Amount() *big.Rat

Amount returns the decimal value as an exact rational — fractional divided by the currency's subunit_to_unit — the analogue of Money#amount / Money#to_d.

func (*Money) Bank

func (m *Money) Bank() Bank

Bank returns the money's exchange bank, the analogue of Money#bank.

func (*Money) Cents

func (m *Money) Cents() int64

Cents is an alias for Money.Fractional, matching Money#cents.

func (*Money) Cmp

func (m *Money) Cmp(other *Money) (int, error)

Cmp compares m to other, returning -1, 0 or 1, matching Money#<=>. When either side is zero the raw fractional values are compared directly; otherwise other is exchanged to m's currency first. It returns an error when a needed exchange fails.

func (*Money) Currency

func (m *Money) Currency() *Currency

Currency returns the money's currency, the analogue of Money#currency.

func (*Money) Div

func (m *Money) Div(value *big.Rat) (*Money, error)

Div returns m divided by a scalar, matching Money#/ (Money / Numeric => Money). The quotient is rounded back to an integer number of minor units with the default rounding mode. It returns an error on division by zero.

func (*Money) DivInt

func (m *Money) DivInt(value int64) (*Money, error)

DivInt is a convenience wrapper for Money.Div by an integer scalar.

func (*Money) DivModInt

func (m *Money) DivModInt(value int64) (*Money, *Money, error)

DivModInt returns the integer quotient and Money remainder of dividing m by an integer scalar, matching Money#divmod(Integer). The quotient is a Money.

func (*Money) DivModMoney

func (m *Money) DivModMoney(other *Money) (int64, *Money, error)

DivModMoney returns the integer quotient and Money remainder of dividing m by another Money, matching Money#divmod(Money). other is first exchanged to m's currency.

func (*Money) DivMoney

func (m *Money) DivMoney(other *Money) (*big.Rat, error)

DivMoney returns the ratio m / other as an exact rational, matching the Money / Money form of Money#/ (which returns a Float in the gem). other is first exchanged to m's currency. It returns an error on a zero divisor.

func (*Money) Eql

func (m *Money) Eql(other *Money) bool

Eql reports whether m and other have the same fractional value and currency, matching Money#eql? with strict comparison (0 USD is not 0 EUR).

func (*Money) ExchangeTo

func (m *Money) ExchangeTo(to *Currency) (*Money, error)

ExchangeTo converts m into another currency using m's bank, the analogue of Money#exchange_to. It is a no-op when already in the target currency.

func (*Money) Format

func (m *Money) Format(opts Options) string

Format renders the amount as a price string per the given options, matching Money#format / Money::Formatter. Passing the zero Options{} reproduces the gem's default formatting for the currency.

func (*Money) Fractional

func (m *Money) Fractional() int64

Fractional returns the amount in minor units (cents), the analogue of Money#fractional / Money#cents.

func (*Money) Inspect

func (m *Money) Inspect() string

Inspect returns the gem's #<Money fractional:… currency:…> debug string, matching Money#inspect.

func (*Money) ModuloInt

func (m *Money) ModuloInt(value int64) (*Money, error)

ModuloInt returns m modulo an integer scalar, matching Money#modulo(Integer) / Money#%.

func (*Money) ModuloMoney

func (m *Money) ModuloMoney(other *Money) (*Money, error)

ModuloMoney returns m modulo another Money, matching Money#modulo(Money).

func (*Money) Mul

func (m *Money) Mul(value *big.Rat) *Money

Mul returns m multiplied by a scalar, matching Money#*. A non-integer product is rounded back to an integer number of minor units with the default rounding mode (the gem's return_value on the resulting BigDecimal).

func (*Money) MulInt

func (m *Money) MulInt(value int64) *Money

MulInt is a convenience wrapper for Money.Mul by an integer scalar; the product is always exact.

func (*Money) Neg

func (m *Money) Neg() *Money

Neg returns a Money with the opposite sign, matching Money#-@.

func (*Money) Negative

func (m *Money) Negative() bool

Negative reports whether the amount is less than zero, matching Money#negative?.

func (*Money) Nonzero

func (m *Money) Nonzero() *Money

Nonzero returns m when non-zero, else nil, matching Money#nonzero?.

func (*Money) Positive

func (m *Money) Positive() bool

Positive reports whether the amount is greater than zero, matching Money#positive?.

func (*Money) RemainderInt

func (m *Money) RemainderInt(value int64) (*Money, error)

RemainderInt returns the remainder of m and an integer scalar, matching Money#remainder. Unlike modulo it takes the sign of the dividend: when the operands have opposite signs it is modulo(val) - val.

func (*Money) Round

func (m *Money) Round(mode RoundingMode) *Money

Round returns a Money whose fractional value is rounded to an integer with the given mode — a no-op for the already-integer fractional this package holds, but provided for API parity with Money#round.

func (*Money) Split

func (m *Money) Split(n int) []*Money

Split divides m evenly into n parts without losing pennies — the analogue of Money#split(n) (an alias of allocate with equal weights). It panics when n < 1.

func (*Money) String

func (m *Money) String() string

String returns the amount as a plain decimal string with no symbol and no thousands separator, matching Money#to_s (no_cents_if_whole for zero-decimal currencies).

func (*Money) Sub

func (m *Money) Sub(other *Money) (*Money, error)

Sub returns the difference m - other. When other has a different currency it is first exchanged to m's currency, matching Money#-.

func (*Money) Symbol

func (m *Money) Symbol() string

Symbol returns the currency symbol, or "¤" when the currency has none — the analogue of Money#symbol.

func (*Money) ToF

func (m *Money) ToF() float64

ToF returns the amount as a float64, matching Money#to_f. Prefer Money.Amount for exact decimals; floats lose precision.

func (*Money) ToI

func (m *Money) ToI() int64

ToI returns the whole-unit part of the amount as an integer (truncated toward zero), matching Money#to_i.

func (*Money) ToNearestCashValue

func (m *Money) ToNearestCashValue() (*Money, error)

ToNearestCashValue rounds the amount to the nearest multiple of the currency's smallest_denomination, matching Money#to_nearest_cash_value. It returns an error when the currency has no smallest denomination.

func (*Money) WithCurrency

func (m *Money) WithCurrency(c *Currency) *Money

WithCurrency returns a Money with the same fractional value but a new currency, performing no conversion — the analogue of Money#with_currency.

func (*Money) Zero

func (m *Money) Zero() bool

Zero reports whether the amount is zero, matching Money#zero?.

type Options

type Options struct {
	// DisplayFree, when set, formats a zero amount as its string (or "free" when
	// set to the empty string via DisplayFreeText).
	DisplayFree     bool
	DisplayFreeText *string // custom free text; nil => "free"

	// WithCurrency appends the ISO code (e.g. " USD") after the amount.
	WithCurrency bool

	// NoCents omits the decimal part entirely.
	NoCents bool
	// NoCentsIfWhole omits the decimal part only when it is all zeros.
	NoCentsIfWhole bool
	// DropTrailingZeros trims trailing zeros from the decimal part.
	DropTrailingZeros bool

	// Symbol controls the currency symbol. nil => default (the currency symbol);
	// use SymbolOff(), SymbolOn() or SymbolString(s) to build it.
	Symbol *SymbolRule

	// Disambiguate uses the currency's disambiguate_symbol when available.
	Disambiguate bool

	// DecimalMark overrides the decimal separator; nil => currency/default ".".
	DecimalMark *string
	// ThousandsSeparator overrides the grouping separator; nil => currency/
	// default. A pointer to "" (or a false-y value) disables grouping.
	ThousandsSeparator *string

	// SignPositive prefixes a "+" to positive amounts.
	SignPositive bool
	// SignBeforeSymbol places the sign before the symbol (e.g. "-$1.00").
	SignBeforeSymbol bool

	// Format overrides the "%u%n" template; nil => currency/symbol-position
	// default.
	Format *string

	// SouthAsianNumberFormatting groups with the Indian lakh/crore pattern.
	SouthAsianNumberFormatting bool

	// IgnoreDefaults skips merging Money's process-wide default rules (used by
	// Money#to_s). This package has no process-wide default rules, so it only
	// affects nothing today, but is kept for API parity.
	IgnoreDefaults bool
}

Options are the formatting rules for Money.Format, the analogue of the hash Money#format accepts. Tri-state fields (String / Symbol / …) use pointers so a nil pointer means "not supplied" (fall back to defaults) and a non-nil pointer carries an explicit value — matching how the gem distinguishes an absent key from a false/empty value.

type RoundingMode

type RoundingMode int

RoundingMode selects how a non-integer number of minor units is rounded back to an integer, mirroring the BigDecimal::ROUND_* modes the gem uses. The gem's default is HalfUp (round half away from zero).

const (
	// HalfUp rounds to the nearest neighbour; ties round away from zero
	// (BigDecimal::ROUND_HALF_UP — the gem default).
	HalfUp RoundingMode = iota
	// HalfDown rounds to the nearest neighbour; ties round toward zero.
	HalfDown
	// HalfEven rounds to the nearest neighbour; ties round to the even neighbour
	// (banker's rounding).
	HalfEven
	// Up rounds away from zero (ceil in magnitude).
	Up
	// Down truncates toward zero.
	Down
	// Ceiling rounds toward positive infinity.
	Ceiling
	// Floor rounds toward negative infinity.
	Floor
)

type SingleCurrency

type SingleCurrency struct{}

SingleCurrency is a bank that refuses every exchange, the analogue of Money::Bank::SingleCurrency — useful for apps that operate in one currency.

func NewSingleCurrency

func NewSingleCurrency() *SingleCurrency

NewSingleCurrency returns a single-currency bank.

func (*SingleCurrency) ExchangeWith

func (b *SingleCurrency) ExchangeWith(from *Money, to *Currency) (*Money, error)

ExchangeWith always returns a *DifferentCurrencyError unless from and to are the same currency, matching SingleCurrency#exchange_with.

type SymbolRule

type SymbolRule struct {
	// contains filtered or unexported fields
}

SymbolRule is the tri-state for the :symbol option: off, on (currency symbol), or a fixed string.

func SymbolOff

func SymbolOff() *SymbolRule

SymbolOff disables the symbol (:symbol => false).

func SymbolOn

func SymbolOn() *SymbolRule

SymbolOn selects the currency's own symbol (:symbol => true).

func SymbolString

func SymbolString(s string) *SymbolRule

SymbolString forces a specific symbol string (:symbol => "ƒ").

type UnknownCurrencyError

type UnknownCurrencyError struct{ ID string }

UnknownCurrencyError is returned when a currency id / code cannot be resolved, mirroring Money::Currency::UnknownCurrency.

func (*UnknownCurrencyError) Error

func (e *UnknownCurrencyError) Error() string

type UnknownRateError

type UnknownRateError struct{ From, To string }

UnknownRateError is returned when a bank has no rate for a currency pair, mirroring Money::Bank::UnknownRate.

func (*UnknownRateError) Error

func (e *UnknownRateError) Error() string

type VariableExchange

type VariableExchange struct {
	// contains filtered or unexported fields
}

VariableExchange is a bank that exchanges using rates injected by the host, the analogue of Money::Bank::VariableExchange with the in-memory rate store. Rates are keyed by ISO-code pair and each direction is independent.

func NewVariableExchange

func NewVariableExchange() *VariableExchange

NewVariableExchange returns an empty variable-exchange bank.

func (*VariableExchange) AddRate

func (b *VariableExchange) AddRate(from, to *Currency, rate *big.Rat) *big.Rat

AddRate registers the rate for converting from -> to and returns it, matching VariableExchange#add_rate / #set_rate. Only this direction is set.

func (*VariableExchange) ExchangeWith

func (b *VariableExchange) ExchangeWith(from *Money, to *Currency) (*Money, error)

ExchangeWith converts from into to using the stored rate, matching VariableExchange#exchange_with. The fractional amount is first rescaled for the two currencies' subunit_to_unit, multiplied by the rate, then rounded back to an integer number of minor units with the default rounding mode.

func (*VariableExchange) GetRate

func (b *VariableExchange) GetRate(from, to *Currency) (*big.Rat, bool)

GetRate returns the rate for from -> to and whether it is known, matching VariableExchange#get_rate.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL