AshWeight (ash_weight v0.1.0)

Copy Markdown View Source

A metric weight type for Ash.

Stored canonically as integer milligrams (BIGINT in Postgres), with ergonomic conversions to grams and kilograms via Decimal to avoid float drift.

Usage

attribute :weight, AshWeight, constraints: [min: 0]

AshWeight.new(1.5, :g)        # => %AshWeight{mg: 1500}
AshWeight.from_kg("2.25")     # => %AshWeight{mg: 2_250_000}
AshWeight.to_kg(weight)       # => #Decimal<0.0015>
to_string(AshWeight.from_kg(1.5))  # => "1.5 kg"

Accepted input shapes for Ash.Type.cast_input/3:

  • %AshWeight{}
  • integer — treated as milligrams
  • {value, :mg | :g | :kg} — explicit unit

  • %{value: _, unit: _} / %{"value" => _, "unit" => _} — form data
  • nil

Summary

Functions

Adds two weights.

Compares two weights. Returns :lt, :eq, or :gt.

Builds a weight from a gram value (mass × 1_000 mg).

Builds a weight from a kilogram value (mass × 1_000_000 mg).

Builds a weight from a milligram value.

Multiplies a weight by a scalar.

Builds a weight from value in the given metric unit (default :mg).

Returns the weight in grams as a Decimal.

Returns the weight in kilograms as a Decimal.

Returns the weight in integer milligrams.

Types

t()

@type t() :: %AshWeight{mg: integer()}

unit()

@type unit() :: :mg | :g | :kg

Functions

add(ash_weight1, ash_weight2)

@spec add(t(), t()) :: t()

Adds two weights.

compare(ash_weight1, ash_weight2)

@spec compare(t(), t()) :: :lt | :eq | :gt

Compares two weights. Returns :lt, :eq, or :gt.

from_g(value)

@spec from_g(integer() | float() | Decimal.t() | String.t()) :: t()

Builds a weight from a gram value (mass × 1_000 mg).

from_kg(value)

@spec from_kg(integer() | float() | Decimal.t() | String.t()) :: t()

Builds a weight from a kilogram value (mass × 1_000_000 mg).

from_mg(value)

@spec from_mg(integer() | float() | Decimal.t() | String.t()) :: t()

Builds a weight from a milligram value.

handle_change?()

multiply(ash_weight, scalar)

@spec multiply(t(), integer() | float() | Decimal.t() | String.t()) :: t()

Multiplies a weight by a scalar.

new(value, unit \\ :mg)

@spec new(value :: integer() | float() | Decimal.t() | String.t(), unit()) :: t()

Builds a weight from value in the given metric unit (default :mg).

value may be an integer, float, Decimal, or numeric string. Internally normalized through Decimal arithmetic and rounded to integer milligrams, so new(0.1, :g) is exactly 100 mg with no float drift.

prepare_change?()

subtract(ash_weight1, ash_weight2)

@spec subtract(t(), t()) :: t()

Subtracts b from a.

to_g(ash_weight)

@spec to_g(t()) :: Decimal.t()

Returns the weight in grams as a Decimal.

to_kg(ash_weight)

@spec to_kg(t()) :: Decimal.t()

Returns the weight in kilograms as a Decimal.

to_mg(ash_weight)

@spec to_mg(t()) :: integer()

Returns the weight in integer milligrams.