Skip to content

v0.3.0

Choose a tag to compare

@dannote dannote released this 29 Sep 23:48
· 1 commit to master since this release

Retired on Hex: fast_path: fails to compile. Use 0.3.1.

Breaking changes

  • cast: callbacks return {:ok, value}, :error, or {:error, reason}, like Ecto.Type.cast/1. Rejections become a JSONCodec.Error with reason: :invalid_value, so decode/1 and from_map/1 return errors instead of crashing. Wrap results in {:ok, value}; plain captures like &String.trim/1 need a wrapper.
  • Invalid JSON is a JSONCodec.Error with reason: :invalid_json, not a Jason.DecodeError.
  • use JSONCodec no longer replaces defstruct. A field is required unless its type allows nil or it has a non-nil default, so defstruct name: nil with a non-nullable type is now required.
  • Removed to_map/1 (use dump/1, which respects JSON field names) and the json_schema/0,1 aliases (use schema/0,1).
  • The fast clause is always generated and the fast_path: option has no effect. use JSONCodec rejects unknown options at compile time.
  • Modules outside JSONCodec provide schemas by implementing the JSONCodec.Schema behaviour instead of just exporting json_schema/0; the callback is schema/0.
  • dump/1 returns structs that are not codecs, such as DateTime, unchanged for the JSON encoder instead of flattening their fields.

Changed

  • Parse with Elixir's JSON module on Elixir 1.18+, falling back to Jason, which becomes optional.
  • Generated decoders specialize more at compile time: nested codecs are called directly, atom policies are resolved when the codec compiles, defaults are inlined, and list and map value error paths are built only on failure. On the program facts benchmark this halves BEAM reductions, cuts memory by a third, and brings decoding from about 1.34× to about 1.1× the time of handwritten code.
  • Unknown atom: policies are compile errors instead of failing on the first decoded atom.
  • Defaults bypass cast:, type decoding, and transform:; a missing optional field takes its struct default as is.

Fixed

  • codec/2 options can use module attributes, such as atom: {:enum, @states}; anonymous function callbacks now fail at compile time.
  • Missing required fields report got: nil instead of an internal marker.

Added

  • JSONCodec.Error.details holds the cast's rejection reason or the JSON parser message.