Skip to main content

src/aws@internal@codec@json_document.erl

-module(aws@internal@codec@json_document).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aws/internal/codec/json_document.gleam").
-export([from_dynamic/1, decoder/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(
    " `smithy.api#Document` codec. Documents are \"any JSON value\" — the\n"
    " service doesn't constrain the shape. We carry them as `json.Json`\n"
    " so round-trips are byte-stable: decode a document field, re-encode\n"
    " it, and you get the same JSON back out.\n"
    "\n"
    " Backed by FFI because `gleam_json.Json` is opaque and there's no\n"
    " public constructor for \"raw JSON\". On the Erlang side `Json` is\n"
    " just iodata, so `raw/1` is a no-op cast.\n"
).

-file("src/aws/internal/codec/json_document.gleam", 17).
?DOC(
    " Take a dynamic value (whatever `decode.dynamic` produced) and turn\n"
    " it into a `json.Json`. Round-trips through `aws_ffi:encode_dynamic_to_json`,\n"
    " then casts the resulting binary back to the opaque `Json` type.\n"
).
-spec from_dynamic(gleam@dynamic:dynamic_()) -> gleam@json:json().
from_dynamic(D) ->
    case aws_ffi:encode_dynamic_to_json(D) of
        {ok, Bin} ->
            gleam_json_ffi:json_to_string(Bin);

        {error, _} ->
            gleam@json:null()
    end.

-file("src/aws/internal/codec/json_document.gleam", 27).
?DOC(
    " Decoder for a Document field. Always succeeds — Documents accept\n"
    " any JSON shape including nulls, so failure is never the right\n"
    " answer at this layer.\n"
).
-spec decoder() -> gleam@dynamic@decode:decoder(gleam@json:json()).
decoder() ->
    gleam@dynamic@decode:then(
        {decoder, fun gleam@dynamic@decode:decode_dynamic/1},
        fun(D) -> gleam@dynamic@decode:success(from_dynamic(D)) end
    ).