-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`; `<>` 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`.\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()] ).