From ed8f1c2dee04e13a103880c40e838750e238a712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibaut=20Barr=C3=A8re?= Date: Sun, 21 May 2023 15:09:24 +0200 Subject: [PATCH] Document Jason.Fragment (#166) * Add a test * Document Jason.Fragment * Add something in the readme --- README.md | 14 ++++++++++++++ lib/fragment.ex | 10 ++++++++++ test/encode_test.exs | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/README.md b/README.md index 3d0ca71..1ff40b3 100644 --- a/README.md +++ b/README.md @@ -135,6 +135,20 @@ Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...]) Protocol.derive(Jason.Encoder, NameOfTheStruct) ``` +## Injecting an already encoded JSON inside a to-be-encoded structure + +If parts of the to-be-encoded structure are already JSON-encoded, you can +use `Jason.Fragment` to mark the parts as already encoded, and avoid a +decoding/encoding roundtrip. + +```elixir +already_encoded_json = Jason.encode!(%{hello: "world"}) +Jason.encode!(%{foo: Jason.Fragment.new(already_encoded_json)}) +```` + +This feature is especially useful if you need to cache a part of the JSON, +or if it is already provided by another system (e.g. `jsonb_agg` with Postgres). + ## License Jason is released under the Apache License 2.0 - see the [LICENSE](LICENSE) file. diff --git a/lib/fragment.ex b/lib/fragment.ex index 2bcde6b..db26c7c 100644 --- a/lib/fragment.ex +++ b/lib/fragment.ex @@ -1,4 +1,14 @@ defmodule Jason.Fragment do + @moduledoc ~S""" + Provides a way to inject an already-encoded JSON structure into a + to-be-encoded structure in optimized fashion. + + This avoids a decoding/encoding round-trip for the subpart. + + This feature can be used for caching parts of the JSON, or delegating + the generation of the JSON to a third-party system (e.g. Postgres). + """ + defstruct [:encode] def new(iodata) when is_list(iodata) or is_binary(iodata) do diff --git a/test/encode_test.exs b/test/encode_test.exs index 4f5d33c..7da4da9 100644 --- a/test/encode_test.exs +++ b/test/encode_test.exs @@ -115,6 +115,11 @@ defmodule Jason.EncoderTest do assert to_json(multi_key_map) == ~s({"foo":"foo1","foo":"foo2"}) end + test "Fragment" do + pre_encoded_json = Jason.encode!(%{hello: "world", test: 123}) + assert to_json(%{foo: Jason.Fragment.new(pre_encoded_json)}) == ~s({"foo":{"hello":"world","test":123}}) + end + defmodule Derived do @derive Encoder defstruct name: ""