denom

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Dec 6, 2025 License: MIT Imports: 6 Imported by: 0

README

denom – Monetary Amount & Formatting for Go

denom logo

Small, dependency-free helpers for representing money with integers and formatting it consistently across APIs, logs, and UIs.

Install

go get github.com/0x4A756E65/denom

Core Ideas

  • Amount stores only minor units (int64) plus a Currency that defines its decimal Scale (business precision, e.g., 2 for USD cents, 0 for JPY, 6 for USDC).
  • Formatter renders an Amount into a reusable View with precomputed strings: raw minor, normalized major string, optional float, formatted display, sign, and currency metadata.
  • Arithmetic is integer-only; formatting is configurable (grouping, symbols, ISO/accounting style, optional plus, custom zero text).

Quick Start

amt := denom.FromMinor(5_002_344, denom.USD) // 50,023.44 USD
view := denom.US().View(amt)

fmt.Println(view.Formatted) // "$50,023.44"
fmt.Println(view.Major)     // "50023.44"
fmt.Println(view.Minor)     // 5002344
fmt.Println(view.Currency)  // "USD"

Parse from a string with scale-aware validation:

amt, err := denom.FromMajorString("1234.567890", denom.USDC) // scale 6
if err != nil {
	log.Fatal(err)
}
iso := denom.NewFormatter(denom.FormatterConfig{Style: denom.StyleISO, UseGrouping: true})
fmt.Println(iso.Format(amt)) // "USDC 1,234.567890"

Use accounting style and compact display:

loss := denom.FromMinor(-12_345, denom.USD) // -123.45
fmt.Println(denom.USAccounting().Format(loss))      // "($123.45)"
fmt.Println(denom.US().FormatCompact(loss.MulInt(10))) // "-$1.2k"

Run the examples:

go run ./examples/demo   # single program with multiple scenarios

Formatting Styles

  • StyleCurrency (default): $50,023.44
  • StyleNoSymbol: 50,023.44
  • StyleISO: USD 50,023.44
  • StyleAccounting: ($50,023.44) for negatives

Flags: UseGrouping (commas), ShowPlus (e.g., +$50.00), ZeroText (e.g., ).

Predefined Currencies

Fiat: USD, EUR, GBP, CHF, CAD, JPY, CNY, AUD, NZD, SGD, SEK, NOK, MXN, BRL, INR, HKD, KRW, TRY, ZAR, PLN, RUB.
Crypto: BTC (scale 8), ETH (scale 6).
Stablecoins: USDC (scale 6), USDT (scale 6).
Use denom.Lookup(code) or define your own Currency with the scale your product uses.

Development

go test ./...

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	USD = Currency{Code: "USD", Symbol: "$", Scale: 2}
	EUR = Currency{Code: "EUR", Symbol: "€", Scale: 2}
	GBP = Currency{Code: "GBP", Symbol: "£", Scale: 2}
	CHF = Currency{Code: "CHF", Symbol: "CHF", Scale: 2}
	CAD = Currency{Code: "CAD", Symbol: "CA$", Scale: 2}

	JPY = Currency{Code: "JPY", Symbol: "¥", Scale: 0}
	CNY = Currency{Code: "CNY", Symbol: "¥", Scale: 2}
	AUD = Currency{Code: "AUD", Symbol: "A$", Scale: 2}
	NZD = Currency{Code: "NZD", Symbol: "NZ$", Scale: 2}
	SGD = Currency{Code: "SGD", Symbol: "S$", Scale: 2}

	SEK = Currency{Code: "SEK", Symbol: "kr", Scale: 2}
	NOK = Currency{Code: "NOK", Symbol: "kr", Scale: 2}
	MXN = Currency{Code: "MXN", Symbol: "MX$", Scale: 2}
	BRL = Currency{Code: "BRL", Symbol: "R$", Scale: 2}
	INR = Currency{Code: "INR", Symbol: "₹", Scale: 2}
	HKD = Currency{Code: "HKD", Symbol: "HK$", Scale: 2}
	KRW = Currency{Code: "KRW", Symbol: "₩", Scale: 0}
	TRY = Currency{Code: "TRY", Symbol: "₺", Scale: 2}
	ZAR = Currency{Code: "ZAR", Symbol: "R", Scale: 2}
	PLN = Currency{Code: "PLN", Symbol: "zł", Scale: 2}
	RUB = Currency{Code: "RUB", Symbol: "₽", Scale: 2}
)

Predefined fiat currencies.

View Source
var (
	BTC = Currency{Code: "BTC", Symbol: "₿", Scale: 8}
	ETH = Currency{Code: "ETH", Symbol: "Ξ", Scale: 6}
)

Predefined crypto majors.

View Source
var (
	USDC = Currency{Code: "USDC", Symbol: "USDC", Scale: 6}
	USDT = Currency{Code: "USDT", Symbol: "USDT", Scale: 6}
)

Predefined USD stablecoins (business precision).

View Source
var Registry = map[string]Currency{
	"USD": USD, "EUR": EUR, "GBP": GBP,
	"CHF": CHF, "CAD": CAD, "JPY": JPY,
	"CNY": CNY, "AUD": AUD, "NZD": NZD,
	"SGD": SGD, "SEK": SEK, "NOK": NOK,
	"MXN": MXN, "BRL": BRL, "INR": INR,
	"HKD": HKD, "KRW": KRW, "TRY": TRY,
	"ZAR": ZAR, "PLN": PLN, "RUB": RUB,
	"BTC": BTC, "ETH": ETH,
	"USDC": USDC, "USDT": USDT,
}

Registry is a helper map for code-based lookups.

Functions

This section is empty.

Types

type Amount

type Amount struct {
	Minor    int64
	Currency Currency
}

Amount represents a value in a specific currency.

func FromMajorFloat

func FromMajorFloat(f float64, c Currency) Amount

FromMajorFloat is a convenience constructor that rounds half away from zero to c.Scale decimal places.

func FromMajorString

func FromMajorString(s string, c Currency) (Amount, error)

FromMajorString parses a major-unit decimal string into an Amount. The string may start with an optional sign and must contain at most c.Scale fractional digits (no grouping separators).

func FromMinor

func FromMinor(minor int64, c Currency) Amount

FromMinor constructs an Amount from a minor-unit integer.

func (Amount) Add

func (a Amount) Add(b Amount) Amount

Add adds two Amounts; panics if currencies differ or on overflow.

func (Amount) IsNegative

func (a Amount) IsNegative() bool

IsNegative reports whether the amount is negative.

func (Amount) IsZero

func (a Amount) IsZero() bool

IsZero reports whether the amount is zero.

func (Amount) MajorFloat

func (a Amount) MajorFloat() float64

MajorFloat returns a best-effort float64 representation.

func (Amount) MajorString

func (a Amount) MajorString() string

MajorString returns a normalized signless decimal string using the currency scale.

func (Amount) MinorInt

func (a Amount) MinorInt() int64

MinorInt returns the raw minor-unit integer.

func (Amount) MulInt

func (a Amount) MulInt(n int64) Amount

MulInt multiplies an Amount by an integer factor; panics on overflow.

func (Amount) Neg

func (a Amount) Neg() Amount

Neg returns the additive inverse of the amount; panics on overflow.

func (Amount) SameCurrency

func (a Amount) SameCurrency(b Amount) bool

SameCurrency reports whether a and b share the same currency code and scale.

func (Amount) Sub

func (a Amount) Sub(b Amount) Amount

Sub subtracts b from a; panics if currencies differ or on overflow.

type Currency

type Currency struct {
	Code   string
	Symbol string
	Scale  int
}

Currency describes a fiat, crypto, or token with a business precision scale.

func Lookup

func Lookup(code string) (Currency, bool)

Lookup returns a currency from the registry by code.

type Formatter

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

Formatter renders amounts according to the config.

func NewFormatter

func NewFormatter(cfg FormatterConfig) Formatter

NewFormatter creates a formatter from the given config.

func US

func US() Formatter

US returns a default US-style formatter.

func USAccounting

func USAccounting() Formatter

USAccounting returns a formatter with accounting negatives.

func (Formatter) Format

func (f Formatter) Format(a Amount) string

Format returns a human-friendly string for the amount.

func (Formatter) FormatCompact

func (f Formatter) FormatCompact(a Amount) string

FormatCompact returns a compact representation like "$50k" or "$1.2M".

func (Formatter) View

func (f Formatter) View(a Amount) View

View converts an Amount into a rich View struct.

type FormatterConfig

type FormatterConfig struct {
	Style       Style
	UseGrouping bool
	ShowPlus    bool
	ZeroText    string
	Locale      string
}

FormatterConfig controls formatting behavior.

type Style

type Style int

Style controls how formatted amounts are rendered.

const (
	StyleCurrency Style = iota
	StyleNoSymbol
	StyleISO
	StyleAccounting
)

type View

type View struct {
	Minor int64   `json:"minor"`
	Major string  `json:"major"`
	Float float64 `json:"float,omitempty"`

	Formatted string `json:"formatted"`
	Sign      string `json:"sign,omitempty"`

	Currency       string `json:"currency"`
	CurrencySymbol string `json:"currency_symbol"`
}

View represents a formatted perspective on an amount.

Directories

Path Synopsis
examples
basic command
demo command
more command

Jump to

Keyboard shortcuts

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