Documentation
¶
Overview ¶
Package types defines the CalcMark type system.
CalcMark supports several value types for calculations and data representation. All types implement the Type interface which provides string representation.
Core Types ¶
- Number: Arbitrary-precision decimal numbers
- Currency: Monetary values with currency symbol/code
- Quantity: Physical quantities with units (e.g., "5 kg", "10 meters")
- Date: Calendar dates with date arithmetic
- Time: Time of day with timezone support
- Duration: Time durations (e.g., "5 days", "3 hours")
- Boolean: True/false values
Number Type ¶
Numbers use arbitrary-precision decimals via shopspring/decimal:
num := types.NewNumber(decimal.NewFromFloat(3.14159)) fmt.Println(num.String()) // "3.14159"
Supports thousands separators:
1,000 1_000_000
Currency Type ¶
Currency values combine a decimal amount with a symbol or ISO code:
usd := types.NewCurrency(decimal.NewFromInt(100), "$") eur := types.NewCurrencyFromCode(decimal.NewFromInt(50), "EUR")
Supported symbols: $, €, £, ¥ Supports ISO 4217 currency codes (e.g., USD, EUR, GBP, JPY)
Quantity Type ¶
Physical quantities with units:
mass := types.NewQuantity(decimal.NewFromInt(5), "kg") length := types.NewQuantity(decimal.NewFromInt(10), "meters")
Supports SI and US customary units:
- Length: meters, feet, kilometers, miles, etc.
- Mass: kilograms, pounds, grams, etc.
- Volume: liters, gallons, cups, etc.
Date Type ¶
Calendar dates with arithmetic operations:
today := types.NewDateFromTime(time.Now()) nextWeek := today.AddDays(7) daysBetween := today.DaysBetween(nextWeek) // 7
Time Type ¶
Time of day with timezone support:
morning := types.NewTime(9, 30, 0, false, 0) // 9:30 AM UTC evening := types.NewTime(6, 0, 0, true, -300) // 6:00 PM EST
Duration Type ¶
Time durations for date arithmetic:
week := types.NewDuration(7, types.DurationUnitDay) hour := types.NewDuration(1, types.DurationUnitHour)
Boolean Type ¶
Simple true/false values:
t := types.NewBoolean(true) f := types.NewBoolean(false)
Type Conversions ¶
The type system maintains type safety while allowing sensible conversions:
- Currency + Number → Currency (preserves currency)
- Currency + Currency (different) → Number (drops units)
- Quantity + Quantity (compatible) → Quantity (first unit wins)
Performance ¶
All type operations are designed for speed and use efficient decimal arithmetic. String formatting is optimized for display/debugging.
Index ¶
- Variables
- func GetCurrencySymbol(code string) string
- func IsCurrencyCode(s string) bool
- func IsTimeUnit(unit string) bool
- func IsValidDurationUnit(unit string) bool
- func NormalizeCurrencyCode(s string) string
- func NormalizeTimeUnit(unit string) string
- func PeriodToPeriodsPerYear(period string) (int, bool)
- func TimeUnitToSeconds(unit string) (decimal.Decimal, error)
- func ToDecimal(t Type) (decimal.Decimal, error)
- type Boolean
- type Currency
- type Date
- type Duration
- type Number
- type Percentage
- type Quantity
- type Rate
- type Time
- type Type
- type TypeError
Constants ¶
This section is empty.
Variables ¶
var CodeToSymbol = map[string]string{
"USD": "$",
"EUR": "€",
"GBP": "£",
"JPY": "¥",
}
CodeToSymbol maps ISO 4217 codes to display symbols. This is the reverse of SymbolToCode.
var DurationToSeconds = map[string]int64{
"second": 1,
"seconds": 1,
"minute": 60,
"minutes": 60,
"hour": 3600,
"hours": 3600,
"day": 86400,
"days": 86400,
"week": 604800,
"weeks": 604800,
"month": 2592000,
"months": 2592000,
"year": 31536000,
"years": 31536000,
}
DurationToSeconds provides conversion factors to seconds (approximate for months/years). Uses int64 for whole-second units. Milliseconds are handled separately in conversion functions.
var SymbolToCode = map[string]string{
"$": "USD",
"€": "EUR",
"£": "GBP",
"¥": "JPY",
}
SymbolToCode maps currency symbols to their ISO 4217 codes. This allows normalization of common symbols to standard codes.
Functions ¶
func GetCurrencySymbol ¶
GetCurrencySymbol returns the display symbol for a currency code. Returns the code itself if no symbol is defined.
func IsCurrencyCode ¶
IsCurrencyCode checks if a string is a known currency code or symbol.
func IsTimeUnit ¶
IsTimeUnit returns true if the given unit is a valid time unit.
func IsValidDurationUnit ¶
IsValidDurationUnit checks if the unit is a valid duration unit.
func NormalizeCurrencyCode ¶
NormalizeCurrencyCode converts a symbol or code to its ISO code. Returns the original string if not recognized.
func NormalizeTimeUnit ¶
NormalizeTimeUnit converts various time unit formats to canonical form. Handles abbreviations, plurals, and adjectival forms (e.g., "monthly" → "month"). Examples: "s" → "second", "seconds" → "second", "sec" → "second", "daily" → "day"
func PeriodToPeriodsPerYear ¶
PeriodToPeriodsPerYear returns how many of the given period fit in one year. Used by growth functions to convert between annual rates and per-period rates. Returns 0 and false for unrecognized periods.
func TimeUnitToSeconds ¶
TimeUnitToSeconds returns the number of seconds in a time unit. Used for accumulation and conversion calculations. Uses the shared DurationToSeconds map from duration.go
Types ¶
type Boolean ¶
type Boolean struct {
Value bool
}
Boolean represents a boolean value (true/false). CalcMark supports multiple boolean representations: true/false, yes/no, t/f, y/n.
func NewBoolean ¶
NewBoolean creates a new Boolean with the given value.
type Currency ¶
type Currency struct {
Value decimal.Decimal
Symbol string // Display symbol: "$", "€", "£", "¥", or ISO code like "USD"
Code string // Normalized ISO 4217 code: "USD", "EUR", "GBP", "JPY"
}
Currency represents a monetary value with a currency symbol and ISO code. It preserves both the display symbol (e.g., "$") and the normalized ISO code (e.g., "USD").
func NewCurrency ¶
NewCurrency creates a new Currency with the given value and symbol/code. If symbolOrCode is a known symbol ($, €, £, ¥), it's mapped to the ISO code. Otherwise, it's used as both the symbol and code.
func NewCurrencyFromString ¶
NewCurrencyFromString creates a Currency from a string value and symbol/code. Returns an error if the string cannot be parsed as a valid number.
func (*Currency) IsSameCurrency ¶
IsSameCurrency checks if two currencies have the same ISO code. This is used for validating currency arithmetic operations.
func (*Currency) String ¶
String returns the precise string representation with symbol and value. This is the machine-readable form used by the JSON formatter. Unlike FormatCurrency() in format/display, String() does NOT add a space between ISO codes and amounts (e.g., "CNY1000.00" not "CNY 1,000.00").
type Date ¶
Date represents a calendar date. Uses Go's time.Time internally for proper date handling (leap years, etc.).
func NewDate ¶
NewDate creates a Date from year, month, and day. If year is 0, uses the current year.
func NewDateFromTime ¶
NewDateFromTime creates a Date from a time.Time value.
func (*Date) DaysBetween ¶
DaysBetween returns the number of days between this date and another.
func (*Date) ShortString ¶
ShortString returns a shorter date format
type Duration ¶
type Duration struct {
Value decimal.Decimal
Unit string // "days", "hours", "minutes", "seconds", "weeks", "months", "years"
}
Duration represents a time duration with a specific unit. Supports: days, hours, minutes, seconds, weeks, months, years.
func NewDuration ¶
NewDuration creates a new Duration with the given value and unit.
func NewDurationFromString ¶
NewDurationFromString creates a Duration from string value and unit.
type Number ¶
Number represents an arbitrary-precision decimal number. It uses the shopspring/decimal package for accurate decimal arithmetic.
func NewNumberFromString ¶
NewNumberFromString creates a Number from a string representation. Returns an error if the string cannot be parsed as a valid number.
type Percentage ¶ added in v1.7.0
Percentage represents a percentage value. The Value field stores the fractional form (e.g., 0.32 for 32%). Percentage preserves its identity through variables and applies widening on + and - operators: value + pct = value * (1 + pct).
func NewPercentage ¶ added in v1.7.0
func NewPercentage(value decimal.Decimal) *Percentage
NewPercentage creates a Percentage from a fractional decimal value. For 32%, pass 0.32.
func (*Percentage) String ¶ added in v1.7.0
func (p *Percentage) String() string
String returns the percentage in human-readable form (e.g., "32%").
type Quantity ¶
type Quantity struct {
Value decimal.Decimal
Unit string
IsNapkin bool // True if this is a napkin estimate (approximate value)
IsExplicit bool // True if unit was explicitly chosen via `in`/`as` conversion
IsPrecise bool // True if full precision requested via `as precise`
}
Quantity represents a value with a physical unit. This is a stub for future implementation with full unit support. For now, it simply stores the value and unit string.
func NewQuantity ¶
NewQuantity creates a new Quantity with the given value and unit.
func NewQuantityFromString ¶
NewQuantityFromString creates a Quantity from a string value and unit.
type Rate ¶
type Rate struct {
// Amount is the numerator (quantity per time unit)
// Can be any Quantity type (GB, requests, dollars, etc.)
Amount *Quantity
// PerUnit is the time unit denominator
// Valid units: "second", "minute", "hour", "day", "week", "month", "year"
PerUnit string
}
Rate represents a rate type: quantity per time period. Examples: 100 MB/s, $0.10/hour, 5 GB/day, 60 meters per second
Rate syntax:
- Slash (no spaces): "100 MB/s", "5 GB/day"
- Word "per" (with spaces): "100 MB per second", "5 GB per day"
Rates are first-class types that enable:
- Accumulation: rate * time = quantity
- Conversion: rate in different time units
- Arithmetic: adding/subtracting compatible rates
func (*Rate) CompoundUnit ¶
CompoundUnit returns the compound unit string for this rate (e.g., "MB/s", "USD/h"). The numerator uses the amount's unit and the denominator uses the abbreviated time unit.
func (*Rate) IsCompatible ¶
IsCompatible checks if two rates can be added/subtracted. Rates are compatible if their amounts have compatible units and same time periods.
type Time ¶
Time represents a time of day with optional timezone offset. Uses Go's time.Time internally.
func NewTime ¶
NewTime creates a Time from hour, minute, second (optional), and UTC offset (optional). hour: 0-23 for 24-hour format, or 1-12 for 12-hour with isPM minute: 0-59 second: 0-59 (use -1 if not specified) isPM: true for PM in 12-hour format, false for AM or 24-hour format utcOffsetMinutes: offset from UTC in minutes (0 for UTC/local time)
type Type ¶
type Type interface {
// String returns a human-readable representation of the value.
// This is used for display purposes and debugging.
String() string
}
Type is the interface that all CalcMark value types implement. All types can be converted to a human-readable string representation.