(.using
  [library
   [lux {"-" and}
    ["$" documentation {"+" documentation:}]
    [control
     ["<>" parser
      ["<[0]>" code]]]
    [data
     ["[0]" text {"+" \n}
      ["%" format {"+" format}]]]
    [macro
     ["[0]" template]]
    [math
     [number
      ["[0]" ratio]]]]]
  [\\library
   ["[0]" /]])

(documentation: (/.Qty unit)
  "A quantity with an associated unit of measurement.")

(documentation: (/.Unit unit)
  "A unit of measurement, to qualify numbers with.")

(documentation: (/.Scale scale)
  "A scale of magnitude.")

(documentation: /.Pure
  "A pure, unit-less quantity.")

(documentation: /.unit:
  (format "Define a unit of measurement."
          \n "Both the name of the type, and the name of the Unit implementation must be specified.")
  [(unit: .public Feet feet)])

(documentation: /.scale:
  "Define a scale of magnitude."
  [(scale: .public Bajillion bajillion
     [1 1,234,567,890])])

(documentation: /.re_scaled
  ""
  [(re_scaled from to quantity)])

(template [<type> <scale>]
  [(`` (documentation: <scale>
         (let [numerator (value@ [/.ratio ratio.#numerator] <scale>)
               denominator (value@ [/.ratio ratio.#denominator] <scale>)]
           (format "The '" (~~ (template.text [<scale>])) "' scale, from " (%.nat numerator) " to " (%.nat denominator) "."))))]

  [/.Kilo /.kilo]
  [/.Mega /.mega]
  [/.Giga /.giga]

  [/.Milli /.milli]
  [/.Micro /.micro]
  [/.Nano /.nano]
  )

(template [<unit>]
  [(`` (documentation: <unit>
         (format "The '" (~~ (template.text [<unit>])) "' unit of meaurement.")))]

  [/.gram]
  [/.meter]
  [/.litre]
  [/.second]
  )

(.def: .public documentation
  (.List $.Module)
  ($.module /._
            ""
            [..Qty
             ..Unit
             ..Scale
             ..Pure
             ..unit:
             ..scale:
             ..re_scaled
             ..kilo
             ..mega
             ..giga
             ..milli
             ..micro
             ..nano
             ..gram
             ..meter
             ..litre
             ..second
             ($.default /.Gram)
             ($.default /.Meter)
             ($.default /.Litre)
             ($.default /.Second)
             ($.default /.pure)
             ($.default /.number)
             ($.default /.equivalence)
             ($.default /.order)
             ($.default /.enum)
             ($.default /.Kilo)
             ($.default /.Mega)
             ($.default /.Giga)
             ($.default /.Milli)
             ($.default /.Micro)
             ($.default /.Nano)
             ($.default /.+)
             ($.default /.-)
             ($.default /.*)
             ($.default /./)]
            []))
