num

package
v0.205.0 Latest Latest
Warning

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

Go to latest
Published: Nov 12, 2024 License: Apache-2.0 Imports: 8 Imported by: 9

Documentation

Overview

Package num provides support for dealing with amounts and percentages without rounding errors.

Index

Constants

View Source
const (
	// DefaultFormatterTemplate is the default template used to
	// format numbers for output with their symbols.
	DefaultFormatterTemplate = "%n%u" // e.g. "12%"
)

Variables

View Source
var (
	// Positive validates the that value is greater than or equal to zero.
	Positive = Min(MakeAmount(0, 0)).Exclusive()
	// Negative validates the value is less than or equal to zero.
	Negative = Max(MakeAmount(0, 0)).Exclusive()
	// NotZero validates that the value is not zero.
	NotZero = ThresholdRule{
			// contains filtered or unexported fields
	}
)
View Source
var (
	// AmountZero is a convenience variable for testing against zero amounts.
	AmountZero = MakeAmount(0, 0)
)
View Source
var (
	// ErrIsZero indicates that the value is zero when it should not be.
	ErrIsZero = validation.NewError("validation_is_zero", "must not be zero")
)
View Source
var (
	// PercentageZero is a convenience variable for testing against zero percentages.
	PercentageZero = MakePercentage(0, 0)
)

Functions

This section is empty.

Types

type Amount

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

Amount represents a quantity with decimal places that will not suffer rounding errors like traditional floats. Use cases are assumed to be within the "human manageable domain", i.e. for dealing with counts, money, rates, short distances, etc. Implementation is inspired by https://github.com/shopspring/decimal, but simplified to account for the expectations of GOBL.

func AmountFromFloat64 added in v0.79.1

func AmountFromFloat64(val float64, exp uint32) Amount

AmountFromFloat64 takes a float64 value and converts it into an amount object. The exponential value is used to determine the accuracy of the amount. For example, if you have a float value of `12.345` and an exp of `3`, the resulting amount's underlying value will be `12345`. This method also takes steps to ensure that numbers are rounded correctly as dealing with Floats can have unexpected consequences.

func AmountFromHumanString

func AmountFromHumanString(_ string) (Amount, error)

AmountFromHumanString removes any excess decimal places, commas, or other symbols so that we end up with a simple string that can be parsed.

func AmountFromString

func AmountFromString(val string) (Amount, error)

AmountFromString takes the provided string and tries to convert it into an amount object. Strings must be in a simplified format with no commas and a single `.` to separate the decimal places. Numbers are expected to have a fixed number of decimal places, so if your dealing with a string like `"12.000"`, the accuracy will be assumed to be 3 decimal places.

If you're dealing with numbers from humans which may contain symbols, commas, european style fullstops, underscores, etc. then you should use the `AmountFromHumanString` method.

func MakeAmount

func MakeAmount(val int64, exp uint32) Amount

MakeAmount is a helper to make it a little easier to build a new Amount instance. We use "Make" instead of "New" as there are no pointers.

func NewAmount

func NewAmount(val int64, exp uint32) *Amount

NewAmount provides a pointer to an Amount instance. Normally we'd recommend using the `MakeAmount` method.

func (Amount) Abs added in v0.71.0

func (a Amount) Abs() Amount

Abs provides the absolute value of the amount

func (Amount) Add

func (a Amount) Add(a2 Amount) Amount

Add will add the two amounts together using the base's exponential value for the resulting new amount.

func (Amount) Compare

func (a Amount) Compare(a2 Amount) int

Compare two amounts and return an integer value according to the sign of the difference:

-1 if a <  a2
 0 if a == a2
 1 if a >  a2

func (Amount) Divide

func (a Amount) Divide(a2 Amount) Amount

Divide the amount by the provided amount. Floating points are used for the actual division and then round again to get an int. This prevents rounding errors, but if you want true division with a base and a remainder, use the Split method.

func (Amount) Downscale added in v0.25.2

func (a Amount) Downscale(decrease uint32) Amount

Downscale decreases the amount's exponent by the provided accuracy.

func (Amount) Equals

func (a Amount) Equals(a2 Amount) bool

Equals returns true if the two amounts represent the same value, regardless of the exponential.

func (Amount) Exp

func (a Amount) Exp() uint32

Exp provides the amount's exponent value.

func (Amount) Float64 added in v0.51.0

func (a Amount) Float64() float64

Float64 provides the amount as a float64 value which should be used with caution!

func (Amount) Invert added in v0.13.0

func (a Amount) Invert() Amount

Invert the value.

func (Amount) IsNegative added in v0.71.0

func (a Amount) IsNegative() bool

IsNegative returns true if the amount is less than zero.

func (Amount) IsPositive added in v0.71.0

func (a Amount) IsPositive() bool

IsPositive returns true if the amount is greater than zero.

func (Amount) IsZero

func (a Amount) IsZero() bool

IsZero returns true if the value of the amount is 0.

func (Amount) JSONSchema added in v0.17.0

func (Amount) JSONSchema() *jsonschema.Schema

JSONSchema provides a representation of the struct for usage in Schema.

func (Amount) MarshalText

func (a Amount) MarshalText() ([]byte, error)

MarshalText provides the byte value of the amount. See also the String() method. We always add quotes around values as number representations do not guarantee that tailing 0s will be maintained. It's important to remember that amounts are typically for humans, and thus it makes sense to consider them as strings.

func (Amount) MatchPrecision added in v0.13.0

func (a Amount) MatchPrecision(a2 Amount) Amount

MatchPrecision will rescale the exponent value of the amount so that it matches the scale of the provided amount, but *only* if it is higher.

func (Amount) MinimalString added in v0.13.0

func (a Amount) MinimalString() string

MinimalString provides the amount without any tailing 0s or '.' if one is left over.

func (Amount) Multiply

func (a Amount) Multiply(a2 Amount) Amount

Multiply the amount by the provided amount.

func (Amount) Remove added in v0.25.2

func (a Amount) Remove(percent Percentage) Amount

Remove takes the provided percentage away from the amount assuming it was already applied previously.

func (Amount) Rescale

func (a Amount) Rescale(exp uint32) Amount

Rescale will multiply or divide the amount's value to match the provided exponential. This method will round values in the case of reducing the exponent.

func (Amount) RescaleDown added in v0.80.0

func (a Amount) RescaleDown(exp uint32) Amount

RescaleDown rescales the exponent to the value provided, but only if the amount's exponent is higher. This is useful to ensure that a number has a maximum accuracy.

func (Amount) RescaleRange added in v0.80.0

func (a Amount) RescaleRange(min, max uint32) Amount

RescaleRange will rescale the amount so that it fits within the provided range of exponents. This is useful for ensuring that amounts are within a certain range of accuracy.

func (Amount) RescaleUp added in v0.57.0

func (a Amount) RescaleUp(exp uint32) Amount

RescaleUp will rescale the exponent value of the amount, but only if it is lower than the current exponent.

func (Amount) Split

func (a Amount) Split(x int) (Amount, Amount)

Split divides the amount by x, like Divide, but also provides an additional amount with a remainder so that we avoid rounding errors.

func (Amount) String

func (a Amount) String() string

String returns the simplified string amount.

func (Amount) Subtract

func (a Amount) Subtract(a2 Amount) Amount

Subtract takes away the amount provided from the base.

func (*Amount) UnmarshalJSON

func (a *Amount) UnmarshalJSON(value []byte) error

UnmarshalJSON ensures amounts will be parsed even if defined as numbers in the source JSON.

func (*Amount) UnmarshalText

func (a *Amount) UnmarshalText(value []byte) error

UnmarshalText will decode the amount value, even if it is quoted as a string and will be used for JSON, XML, or any other text unmarshaling.

func (Amount) Upscale added in v0.25.2

func (a Amount) Upscale(increase uint32) Amount

Upscale increases the accuracy of the amount by rescaling the exponent by the provided amount.

func (Amount) Value

func (a Amount) Value() int64

Value provides the amount's value

type Formatter added in v0.71.0

type Formatter struct {
	// DecimalMark is the character used to separate the whole
	// number from the decimal part.
	DecimalMark string
	// ThousandsSeparator is the character used to separate
	// thousands in the whole number.
	ThousandsSeparator string
	// Unit is the string representation or symbol of the unit.
	Unit string
	// Template is the string used to present the number and unit
	// together with two simple placeholders, `%n` for the number and
	// `%u` for the unit.
	Template string
	// NegativeTemplate is the string used to present the number and
	// optional unit together when the number is negative. It might be useful
	// for example to format numbers with brackets around them to represent
	// negative amounts, e.g. `(12)€` instead of `-12€`. By default, the negative
	// symbol is prepended to the number, e.g. `$-12`.
	NegativeTemplate string
	// NumeralSystem determines how numbers should be output. By default
	// this is 'western'.
	NumeralSystem NumeralSystem
}

Formatter is used to define how an amount should be formatted alongside a unit if necessary.

func MakeFormatter added in v0.71.0

func MakeFormatter(decimalMark, thousandsSeparator string) Formatter

MakeFormatter prepares a new formatter with the two main configuration options, decimal and thousands separators.

func (Formatter) Amount added in v0.71.0

func (f Formatter) Amount(amount Amount) string

Amount takes the provided amount and formats it according to the rules of the formatter.

func (Formatter) Percentage added in v0.71.0

func (f Formatter) Percentage(percent Percentage) string

Percentage tries to format the percentage value according to the rules of the formatter, but replacing the unit with a percentage symbol, and using the default template.

func (Formatter) WithNegativeTemplate added in v0.71.0

func (f Formatter) WithNegativeTemplate(template string) Formatter

WithNegativeTemplate sets the template for use with formatting negative amounts with units.

func (Formatter) WithNumeralSystem added in v0.71.0

func (f Formatter) WithNumeralSystem(ns NumeralSystem) Formatter

WithNumeralSystem overrides the default western numeral system with that defined.

func (Formatter) WithTemplate added in v0.71.0

func (f Formatter) WithTemplate(template string) Formatter

WithTemplate sets the template for use with formatting with units.

func (Formatter) WithUnit added in v0.71.0

func (f Formatter) WithUnit(unit string) Formatter

WithUnit providers a formatter with a unit set.

func (Formatter) WithoutUnit added in v0.71.0

func (f Formatter) WithoutUnit() Formatter

WithoutUnit provides a formatter without a unit set.

type NumeralSystem added in v0.71.0

type NumeralSystem string

NumeralSystem describes how to output numbers.

const (
	// NumeralWestern defines the Western Arabic numeral
	// system, and is the default.
	NumeralWestern NumeralSystem = "western"
	// NumeralArabic can be used to output numbers using the
	// Arabic numeral system.
	NumeralArabic NumeralSystem = "arabic"
)

type Percentage

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

Percentage wraps around the regular Amount handler to provide support for percentage values, especially useful for tax rates.

func MakePercentage

func MakePercentage(value int64, exp uint32) Percentage

MakePercentage will make a new Percentage instance with the provided value and exponent.

func NewPercentage

func NewPercentage(value int64, exp uint32) *Percentage

NewPercentage provides a new pointer to a Percentage value. Using MakePercentage is recommend, but this is useful for handling nil values.

func PercentageFromAmount added in v0.71.0

func PercentageFromAmount(a Amount) Percentage

PercentageFromAmount provides the percentage value of the amount ensuring it is correctly scaled.

func PercentageFromString

func PercentageFromString(str string) (Percentage, error)

PercentageFromString builds a percentage value from a provided string. The % symbol will be removed automatically and rescale the stored amount to make future calculations easier. For example, the following two strings will be interpreted equally:

  • `0.160`
  • `16.0%`

func (Percentage) Amount added in v0.71.0

func (p Percentage) Amount() Amount

Amount provides an amount for the percentage that has been rescaled from the underlying value mainly to be used for formatting.

func (Percentage) Base added in v0.75.0

func (p Percentage) Base() Amount

Base provides the underlying amount value of the percentage which is stored internally without any factors applied.

func (Percentage) Compare added in v0.71.0

func (p Percentage) Compare(p2 Percentage) int

Compare two percentages and return an integer value according to the sign of the difference:

-1 if a <  a2
 0 if a == a2
 1 if a >  a2

func (Percentage) Equals

func (p Percentage) Equals(p2 Percentage) bool

Equals wraps around the amount comparison to see if the two percentages have the same value.

func (Percentage) Exp added in v0.71.0

func (p Percentage) Exp() uint32

Exp provides the percentage amount's exponent value.

func (Percentage) Factor

func (p Percentage) Factor() Amount

Factor returns the percentage amount as a factor, essentially adding 1 to the rate.

func (Percentage) From

func (p Percentage) From(a Amount) Amount

From calculates what "percent from" the provided amount would result assuming the rate has already been applied.

func (Percentage) Invert added in v0.69.0

func (p Percentage) Invert() Percentage

Invert provides a new percentage value that is the inverse of the current percentage.

func (Percentage) IsNegative added in v0.71.0

func (p Percentage) IsNegative() bool

IsNegative checks if the percentage is negative.

func (Percentage) IsPositive added in v0.71.0

func (p Percentage) IsPositive() bool

IsPositive checks if the percentage is positive.

func (Percentage) IsZero added in v0.71.0

func (p Percentage) IsZero() bool

IsZero checks if the percentage is zero.

func (Percentage) JSONSchema added in v0.17.0

func (Percentage) JSONSchema() *jsonschema.Schema

JSONSchema provides a representation of the struct for usage in Schema.

func (Percentage) MarshalText

func (p Percentage) MarshalText() ([]byte, error)

MarshalText provides the byte value of the amount. See also the String() method.

func (Percentage) Of

func (p Percentage) Of(a Amount) Amount

Of calculates the "percent of" the provided amount. The exponent of the provided amount is used.

func (Percentage) Rescale added in v0.50.0

func (p Percentage) Rescale(exp uint32) Percentage

Rescale will rescale the percentage value to the provided exponent.

func (Percentage) String

func (p Percentage) String() string

String outputs the percentage value in a human readable way including the percentage symbol.

func (Percentage) StringWithoutSymbol

func (p Percentage) StringWithoutSymbol() string

StringWithoutSymbol provides the percent value without a percent symbol.

func (*Percentage) UnmarshalJSON

func (p *Percentage) UnmarshalJSON(value []byte) error

UnmarshalJSON ensures percentages will be parsed even if defined as numbers in the source JSON.

func (*Percentage) UnmarshalText

func (p *Percentage) UnmarshalText(value []byte) error

UnmarshalText will decode the percentage value, even if it is quoted as a string.

func (Percentage) Value added in v0.71.0

func (p Percentage) Value() int64

Value provides the percentage amount's value

type ThresholdRule added in v0.51.0

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

ThresholdRule is a validator for Amounts and Percentages

func Max added in v0.51.0

func Max(max interface{}) ThresholdRule

Max checks if the value is less than or equal to the provided amount or percentage

func Min added in v0.51.0

func Min(min interface{}) ThresholdRule

Min checks if the value is greater than or equal to the provided amount or percentage

func (ThresholdRule) Exclusive added in v0.51.0

func (r ThresholdRule) Exclusive() ThresholdRule

Exclusive sets the comparison to exclude the boundary value.

func (ThresholdRule) Validate added in v0.51.0

func (r ThresholdRule) Validate(value interface{}) error

Validate checks if the provided value confirms with the threshold rule.

Jump to

Keyboard shortcuts

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