Normandy.JSON
(normandy v2.2.0)
View Source
The one place Normandy encodes and decodes JSON.
Library
Normandy encodes and decodes with Jason, which is a hard dependency. There is no
:adapter setting. decode/1 returns string-keyed maps for objects.
Structs
Before Jason sees a term, every struct in it, at any depth, is either kept or replaced by a plain map:
- A struct with its own
Jason.Encoderimplementation (@derive Jason.Encoder, adefimpl, or one Jason ships:Date,DateTime,Decimal, ...) is kept, and that implementation decides its fields. Its fields are not walked. - Any other struct becomes its map without
:__struct__and:__meta__(an Ecto schema's, whose encoder raises), and its values are walked the same way.
A term JSON cannot express (a tuple, a pid, a reference, a function) is left as
it is: Jason raises on it, and encode/2 returns that exception.
Text for the model
The JSON text Normandy writes into a message for the model (a tool result's text,
a map given as message content) lists every plain map's keys sorted by their text,
at any depth, so the same value is the same text on every node and after a restart
(on OTP 26+ a small atom-keyed map iterates its keys in atom-creation order). Values
and list order are unchanged. A struct without its own Jason.Encoder is written as
its fields, sorted like a plain map. A struct with its own encoder is encoded by that
encoder, whose output is its own, and a Jason.OrderedObject keeps its order (the
plain maps among its values are sorted).
Summary
Functions
Decodes a JSON string; objects become string-keyed maps.
Decodes a JSON string; raises Jason's exception when it is not JSON.
Encodes term, returning {:error, exception} with whatever Jason raised
(Protocol.UndefinedError or Jason.EncodeError), or what walking term
raised (an improper list).
Encodes term; raises Jason's exception when it cannot.
Functions
@spec decode(String.t()) :: {:ok, term()} | {:error, Exception.t()}
Decodes a JSON string; objects become string-keyed maps.
Decodes a JSON string; raises Jason's exception when it is not JSON.
@spec encode( term(), keyword() ) :: {:ok, String.t()} | {:error, Exception.t()}
Encodes term, returning {:error, exception} with whatever Jason raised
(Protocol.UndefinedError or Jason.EncodeError), or what walking term
raised (an improper list).
Encodes term; raises Jason's exception when it cannot.