anteoas / broch

A library for handling numbers with units.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Encoding / decoding

handerpeder opened this issue · comments

Encoding

Say you want to encode a unit as json. Given (meters 10), one reasonable representation is:

[10 , "m"]

another would be:

{
  "amount": 10,
  "unit": "m"
}

to do this you have to write something like:

(require '[anteo.units :as un])
(def m (un/meters 10))

[(un/num m) (anteo.units.impl/->symbol m)]

I think this is useful enought that anteo.units.impl/->symbol should be part of the public API.

Decoding

Say you receive the above json representation and want to construct a unit. Currently there is no good way to do this dynamically. As far as I can tell the only way to construct a meters unit is through the meters construct. So you would need to make a mapping somewhere:

{ "m" meters,
  "kg" kilograms,
  ,,,,; etc
}

I propose we create a constructor that creates a unit given an amount and its symbol. Something like:

(unit 10 "m")

would be equivalent to (meters 10) given that "m" is a registered symbol.

I propose we rename the current unit function to register-unit! and add a unit function as described above. unit doesn't currently have a two element arity so we could just add this to the existing function, but this might make the function confusing.

There are already functions for encoding/decoding in anteo.units.data-literals, named to-edn and from-edn that are used to read/write the tag-literal. I already use these to encode/decode transit in planner in anteo.utils.transit.

But your question reveals that these should probably be elevated to the main ns to highlight them being a part of the public API. And i agree that there should be a simple symbol fn in the API as well.

But the decoding won't work for JSON right?

How would you decode a value coming in at a JSON endpoint as [<amount-number>, <unit-string>]?

something like

(defn from-json [[n s]]
  (let [n (if (string? n) (parse-long n) n)]
   (un/from-edn [n s])) 

Aha, might be this is just an issue of naming then. As a first time user, I would expect to find this function under the core namespace with a more general name.

ahh, right. something like parse maybe?