Documentation ¶
Overview ¶
Package num provides support for dealing with amounts and percentages without rounding errors.
Index ¶
- Constants
- Variables
- type Amount
- func (a Amount) Abs() Amount
- func (a Amount) Add(a2 Amount) Amount
- func (a Amount) Compare(a2 Amount) int
- func (a Amount) Divide(a2 Amount) Amount
- func (a Amount) Downscale(decrease uint32) Amount
- func (a Amount) Equals(a2 Amount) bool
- func (a Amount) Exp() uint32
- func (a Amount) Float64() float64
- func (a Amount) Invert() Amount
- func (a Amount) IsNegative() bool
- func (a Amount) IsPositive() bool
- func (a Amount) IsZero() bool
- func (Amount) JSONSchema() *jsonschema.Schema
- func (a Amount) MarshalText() ([]byte, error)
- func (a Amount) MatchPrecision(a2 Amount) Amount
- func (a Amount) MinimalString() string
- func (a Amount) Multiply(a2 Amount) Amount
- func (a Amount) Remove(percent Percentage) Amount
- func (a Amount) Rescale(exp uint32) Amount
- func (a Amount) RescaleDown(exp uint32) Amount
- func (a Amount) RescaleRange(min, max uint32) Amount
- func (a Amount) RescaleUp(exp uint32) Amount
- func (a Amount) Split(x int) (Amount, Amount)
- func (a Amount) String() string
- func (a Amount) Subtract(a2 Amount) Amount
- func (a *Amount) UnmarshalJSON(value []byte) error
- func (a *Amount) UnmarshalText(value []byte) error
- func (a Amount) Upscale(increase uint32) Amount
- func (a Amount) Value() int64
- type Formatter
- func (f Formatter) Amount(amount Amount) string
- func (f Formatter) Percentage(percent Percentage) string
- func (f Formatter) WithNegativeTemplate(template string) Formatter
- func (f Formatter) WithNumeralSystem(ns NumeralSystem) Formatter
- func (f Formatter) WithTemplate(template string) Formatter
- func (f Formatter) WithUnit(unit string) Formatter
- func (f Formatter) WithoutUnit() Formatter
- type NumeralSystem
- type Percentage
- func (p Percentage) Amount() Amount
- func (p Percentage) Base() Amount
- func (p Percentage) Compare(p2 Percentage) int
- func (p Percentage) Equals(p2 Percentage) bool
- func (p Percentage) Exp() uint32
- func (p Percentage) Factor() Amount
- func (p Percentage) From(a Amount) Amount
- func (p Percentage) Invert() Percentage
- func (p Percentage) IsNegative() bool
- func (p Percentage) IsPositive() bool
- func (p Percentage) IsZero() bool
- func (Percentage) JSONSchema() *jsonschema.Schema
- func (p Percentage) MarshalText() ([]byte, error)
- func (p Percentage) Of(a Amount) Amount
- func (p Percentage) Rescale(exp uint32) Percentage
- func (p Percentage) String() string
- func (p Percentage) StringWithoutSymbol() string
- func (p *Percentage) UnmarshalJSON(value []byte) error
- func (p *Percentage) UnmarshalText(value []byte) error
- func (p Percentage) Value() int64
- type ThresholdRule
Constants ¶
const ( // DefaultFormatterTemplate is the default template used to // format numbers for output with their symbols. DefaultFormatterTemplate = "%n%u" // e.g. "12%" )
Variables ¶
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 } )
var ( // AmountZero is a convenience variable for testing against zero amounts. AmountZero = MakeAmount(0, 0) )
var ( // ErrIsZero indicates that the value is zero when it should not be. ErrIsZero = validation.NewError("validation_is_zero", "must not be zero") )
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
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 ¶
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 ¶
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 ¶
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 ¶
NewAmount provides a pointer to an Amount instance. Normally we'd recommend using the `MakeAmount` method.
func (Amount) Add ¶
Add will add the two amounts together using the base's exponential value for the resulting new amount.
func (Amount) Compare ¶
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 ¶
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
Downscale decreases the amount's exponent by the provided accuracy.
func (Amount) Equals ¶
Equals returns true if the two amounts represent the same value, regardless of the exponential.
func (Amount) Float64 ¶ added in v0.51.0
Float64 provides the amount as a float64 value which should be used with caution!
func (Amount) IsNegative ¶ added in v0.71.0
IsNegative returns true if the amount is less than zero.
func (Amount) IsPositive ¶ added in v0.71.0
IsPositive returns true if the amount is greater than zero.
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 ¶
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
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
MinimalString provides the amount without any tailing 0s or '.' if one is left over.
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 ¶
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
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
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
RescaleUp will rescale the exponent value of the amount, but only if it is lower than the current exponent.
func (Amount) Split ¶
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) UnmarshalJSON ¶
UnmarshalJSON ensures amounts will be parsed even if defined as numbers in the source JSON.
func (*Amount) UnmarshalText ¶
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.
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
MakeFormatter prepares a new formatter with the two main configuration options, decimal and thousands separators.
func (Formatter) Amount ¶ added in v0.71.0
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
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
WithTemplate sets the template for use with formatting with units.
func (Formatter) WithoutUnit ¶ added in v0.71.0
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.