-module(aws@internal@codec@json_float).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/aws/internal/codec/json_float.gleam").
-export([encode/1, decoder/0]).
-export_type([smithy_float/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(
" awsJson special-float helpers.\n"
"\n"
" The AWS JSON protocols (`awsJson1_0`, `awsJson1_1`, plus other\n"
" JSON-family wire formats) encode IEEE 754 specials as JSON strings:\n"
" `\"NaN\"`, `\"Infinity\"`, `\"-Infinity\"`. Plain JSON numbers cover\n"
" every finite float.\n"
"\n"
" **Why a wrapper type instead of raw `Float`:** Erlang's `float()`\n"
" type cannot hold NaN or Infinity. `0.0/0.0` raises `badarith`;\n"
" `binary_to_term` rejects the IEEE 754 NaN bit pattern with\n"
" `badarg`; `<<F/float>>` bit-syntax matching refuses to bind such\n"
" values. So a faithful representation of an awsJson Float field on\n"
" the BEAM target requires an explicit sum type — there's no way to\n"
" pack `NaN` into an Erlang float. Rust's `f64` happens to support\n"
" these natively, which is why aws-sdk-rust gets away with `Option<f64>`.\n"
"\n"
" Matches `aws-sdk-rust`'s `aws-smithy-types::Number::SpecialFloat`\n"
" — same three string spellings, same case-sensitivity.\n"
).
-type smithy_float() :: {float_value, float()} |
na_n |
pos_infinity |
neg_infinity.
-file("src/aws/internal/codec/json_float.gleam", 43).
?DOC(
" Encode a `SmithyFloat` as a JSON value. Finite values become JSON\n"
" numbers; the three IEEE 754 specials become JSON strings, matching\n"
" the awsJson wire spec.\n"
).
-spec encode(smithy_float()) -> gleam@json:json().
encode(V) ->
case V of
{float_value, F} ->
gleam@json:float(F);
na_n ->
gleam@json:string(<<"NaN"/utf8>>);
pos_infinity ->
gleam@json:string(<<"Infinity"/utf8>>);
neg_infinity ->
gleam@json:string(<<"-Infinity"/utf8>>)
end.
-file("src/aws/internal/codec/json_float.gleam", 58).
-spec from_string() -> gleam@dynamic@decode:decoder(smithy_float()).
from_string() ->
gleam@dynamic@decode:then(
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(S) -> case S of
<<"NaN"/utf8>> ->
gleam@dynamic@decode:success(na_n);
<<"Infinity"/utf8>> ->
gleam@dynamic@decode:success(pos_infinity);
<<"-Infinity"/utf8>> ->
gleam@dynamic@decode:success(neg_infinity);
_ ->
gleam@dynamic@decode:failure(
na_n,
<<"expected NaN / Infinity / -Infinity"/utf8>>
)
end end
).
-file("src/aws/internal/codec/json_float.gleam", 54).
?DOC(
" Decoder for a `SmithyFloat`. Accepts plain JSON numbers and the\n"
" three special-float strings.\n"
).
-spec decoder() -> gleam@dynamic@decode:decoder(smithy_float()).
decoder() ->
gleam@dynamic@decode:one_of(
gleam@dynamic@decode:map(
{decoder, fun gleam@dynamic@decode:decode_float/1},
fun(Field@0) -> {float_value, Field@0} end
),
[from_string()]
).