currencyx

package
v1.0.0-beta.230 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

README

currencyx

currencyx contains OpenMeter's shared currency primitives. It keeps fiat behavior compatible with GOBL/ISO currency definitions while allowing product and ledger code to pass configured custom currencies through the same Currency interface.

Fiat Currency

Use Code directly for fiat currencies. Fiat precision comes from the GOBL currency definition and fiat rounding remains half-away-from-zero.

calculator, err := currencyx.Code("USD").Calculator()
if err != nil {
    return err
}

amount := calculator.RoundToPrecision(alpacadecimal.RequireFromString("1.235"))
// amount == 1.24

Custom Currency

Use NewCustomCurrency when the currency is not a known fiat code. Custom currencies carry explicit precision and default to bankers rounding (half-even). Use NewCustomCurrencyWithRounding to opt into half-away-from-zero.

credits, err := currencyx.NewCustomCurrency(currencyx.Code("CREDITS"), 6)
if err != nil {
    return err
}

calculator, err := currencyx.NewCalculator(credits)
if err != nil {
    return err
}

amount := calculator.RoundToPrecision(alpacadecimal.RequireFromString("1.2345678"))
// amount == 1.234568

Allocation

Allocation helpers use the calculator's precision and distribute residual units with a deterministic largest-remainder method. Provide a CompareKey function when equal remainders need a stable domain-specific tie-breaker.

Documentation

Index

Constants

View Source
const (
	MinCodeLength = 3
	MaxCodeLength = 24
	MaxPrecision  = 12

	PostgresCodeSchemaType = "varchar(24)"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AmountAllocation

type AmountAllocation[T any] struct {
	Key    T
	Amount alpacadecimal.Decimal
}

AmountAllocation is the allocated currency amount for one key.

func AllocateByAmount

func AllocateByAmount[T any](calculator Calculator, input AmountAllocationInput[T]) ([]AmountAllocation[T], error)

AllocateByAmount allocates a currency amount across currency amount buckets using the largest remainder quota method. Each item amount is both its proportional weight and its allocation cap.

type AmountAllocationInput

type AmountAllocationInput[T any] struct {
	Amount alpacadecimal.Decimal
	Items  []AmountAllocationItem[T]

	// CompareKey is used as a deterministic tie-breaker when two buckets have
	// the same fractional remainder. If nil, the original item order is used.
	CompareKey func(left, right T) int
}

AmountAllocationInput defines a proportional allocation across currency amount buckets.

type AmountAllocationItem

type AmountAllocationItem[T any] struct {
	Key    T
	Amount alpacadecimal.Decimal
}

AmountAllocationItem defines one currency amount bucket that can receive a proportional allocation. The amount is both the allocation weight and the maximum amount that can be allocated to the key.

type Calculator

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

func NewCalculator

func NewCalculator(cur Currency) (Calculator, error)

func (Calculator) CurrencyCode

func (c Calculator) CurrencyCode() Code

func (Calculator) CurrencyPrecision

func (c Calculator) CurrencyPrecision() int32

func (Calculator) CurrencyType

func (c Calculator) CurrencyType() CurrencyType

func (Calculator) Definition

func (c Calculator) Definition() *currency.Def

func (Calculator) IsRoundedToPrecision

func (c Calculator) IsRoundedToPrecision(amount alpacadecimal.Decimal) bool

func (Calculator) RoundDown

func (Calculator) RoundToPrecision

func (c Calculator) RoundToPrecision(amount alpacadecimal.Decimal) alpacadecimal.Decimal

func (Calculator) RoundingMode

func (c Calculator) RoundingMode() RoundingMode

func (Calculator) Unit

func (c Calculator) Unit() alpacadecimal.Decimal

func (Calculator) Validate

func (c Calculator) Validate() error

type Code

type Code currency.Code

Code represents a fiat or custom currency code. Code values used directly as Currency values are treated as fiat currencies for backwards compatibility.

func NewFiatCurrency

func NewFiatCurrency(code Code) (Code, error)

func (Code) Calculator

func (c Code) Calculator() (Calculator, error)

Calculator provides a currency calculator object. This allows callers to resolve fiat definitions once and then apply currency precision consistently.

func (Code) CurrencyCode

func (c Code) CurrencyCode() Code

func (Code) CurrencyPrecision

func (c Code) CurrencyPrecision() int32

func (Code) CurrencyRoundingMode

func (c Code) CurrencyRoundingMode() RoundingMode

func (Code) CurrencyType

func (c Code) CurrencyType() CurrencyType

func (Code) IsKnownFiat

func (c Code) IsKnownFiat() bool

func (Code) String

func (c Code) String() string

func (Code) Validate

func (c Code) Validate() error

func (Code) ValidateCustom

func (c Code) ValidateCustom() error

func (Code) ValidateFormat

func (c Code) ValidateFormat() error

type Currency

type Currency interface {
	CurrencyCode() Code
	CurrencyType() CurrencyType
	CurrencyPrecision() int32
	CurrencyRoundingMode() RoundingMode
}

func NewCurrency

func NewCurrency(code Code, currencyType CurrencyType, precision int32) (Currency, error)

type CurrencyType

type CurrencyType string
const (
	CurrencyTypeFiat   CurrencyType = "fiat"
	CurrencyTypeCustom CurrencyType = "custom"
)

func (CurrencyType) Validate

func (t CurrencyType) Validate() error

type CustomCurrency

type CustomCurrency struct {
	Code         Code
	Precision    int32
	RoundingMode RoundingMode
}

func NewCustomCurrency

func NewCustomCurrency(code Code, precision int32) (CustomCurrency, error)

func NewCustomCurrencyWithRounding

func NewCustomCurrencyWithRounding(code Code, precision int32, roundingMode RoundingMode) (CustomCurrency, error)

func (CustomCurrency) CurrencyCode

func (c CustomCurrency) CurrencyCode() Code

func (CustomCurrency) CurrencyPrecision

func (c CustomCurrency) CurrencyPrecision() int32

func (CustomCurrency) CurrencyRoundingMode

func (c CustomCurrency) CurrencyRoundingMode() RoundingMode

func (CustomCurrency) CurrencyType

func (c CustomCurrency) CurrencyType() CurrencyType

func (CustomCurrency) Validate

func (c CustomCurrency) Validate() error

type RoundingMode

type RoundingMode string
const (
	RoundingModeHalfAwayFromZero RoundingMode = "half_away_from_zero"
	RoundingModeBankers          RoundingMode = "bankers"
)

func (RoundingMode) Validate

func (m RoundingMode) Validate() error

type WeightedAllocation

type WeightedAllocation[T any] struct {
	Key    T
	Amount alpacadecimal.Decimal
}

WeightedAllocation is the allocated currency amount for one key.

func AllocateByWeight

func AllocateByWeight[T any](calculator Calculator, input WeightedAllocationInput[T]) ([]WeightedAllocation[T], error)

AllocateByWeight allocates a currency amount across keys using their weights and the largest remainder quota method at the currency precision.

type WeightedAllocationInput

type WeightedAllocationInput[T any] struct {
	Amount alpacadecimal.Decimal
	Items  []WeightedAllocationItem[T]

	// CompareKey is used as a deterministic tie-breaker when two items have
	// the same fractional remainder. If nil, the original item order is used.
	CompareKey func(left, right T) int
}

WeightedAllocationInput defines a proportional currency allocation.

type WeightedAllocationItem

type WeightedAllocationItem[T any] struct {
	Key    T
	Weight alpacadecimal.Decimal
}

WeightedAllocationItem defines one key that can receive a proportional allocation from a currency amount. Weight is dimensionless; it does not need to be a currency amount.

Jump to

Keyboard shortcuts

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