-module(postgleam@decode). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/postgleam/decode.gleam"). -export([run/2, success/1, optional/1, int/1, element/3, text/1, bool/1, float/1, bytea/1, uuid/1, uuid_string/1, json/1, jsonb/1, numeric/1, date/1, timestamp/1, timestamptz/1]). -export_type([row_decoder/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -opaque row_decoder(HLB) :: {row_decoder, fun((list(gleam@option:option(postgleam@value:value()))) -> {ok, HLB} | {error, postgleam@error:error()})}. -file("src/postgleam/decode.gleam", 31). ?DOC(" Run a decoder on a row.\n"). -spec run(row_decoder(HLG), list(gleam@option:option(postgleam@value:value()))) -> {ok, HLG} | {error, postgleam@error:error()}. run(Decoder, Row) -> (erlang:element(2, Decoder))(Row). -file("src/postgleam/decode.gleam", 66). ?DOC(" Finalize a decoder chain with a value.\n"). -spec success(HLR) -> row_decoder(HLR). success(Value) -> {row_decoder, fun(_) -> {ok, Value} end}. -file("src/postgleam/decode.gleam", 218). ?DOC( " Make any value decoder nullable (NULL-safe).\n" " Returns `Ok(None)` for NULL, `Ok(Some(val))` for non-NULL.\n" ). -spec optional( fun((gleam@option:option(postgleam@value:value())) -> {ok, HNG} | {error, postgleam@error:error()}) ) -> fun((gleam@option:option(postgleam@value:value())) -> {ok, gleam@option:option(HNG)} | {error, postgleam@error:error()}). optional(Decoder) -> fun(Val) -> case Val of none -> {ok, none}; _ -> case Decoder(Val) of {ok, V} -> {ok, {some, V}}; {error, E} -> {error, E} end end end. -file("src/postgleam/decode.gleam", 235). -spec list_at(list(HNK), integer()) -> {ok, HNK} | {error, nil}. list_at(L, Index) -> case {L, Index} of {[X | _], 0} -> {ok, X}; {[_ | Rest], N} when N > 0 -> list_at(Rest, N - 1); {_, _} -> {error, nil} end. -file("src/postgleam/decode.gleam", 243). -spec value_type_name(postgleam@value:value()) -> binary(). value_type_name(Val) -> case Val of null -> <<"Null"/utf8>>; {boolean, _} -> <<"Boolean"/utf8>>; {integer, _} -> <<"Integer"/utf8>>; {float, _} -> <<"Float"/utf8>>; pos_infinity -> <<"PosInfinity"/utf8>>; neg_infinity -> <<"NegInfinity"/utf8>>; na_n -> <<"NaN"/utf8>>; {text, _} -> <<"Text"/utf8>>; {bytea, _} -> <<"Bytea"/utf8>>; {uuid, _} -> <<"Uuid"/utf8>>; {oid, _} -> <<"Oid"/utf8>>; void -> <<"Void"/utf8>>; {array, _} -> <<"Array"/utf8>>; {date, _} -> <<"Date"/utf8>>; {time, _} -> <<"Time"/utf8>>; {time_tz, _, _} -> <<"TimeTz"/utf8>>; {timestamp, _} -> <<"Timestamp"/utf8>>; {timestamptz, _} -> <<"Timestamptz"/utf8>>; {interval, _, _, _} -> <<"Interval"/utf8>>; {json, _} -> <<"Json"/utf8>>; {jsonb, _} -> <<"Jsonb"/utf8>>; {numeric, _} -> <<"Numeric"/utf8>>; {point, _, _} -> <<"Point"/utf8>>; {inet, _, _, _} -> <<"Inet"/utf8>>; {macaddr, _} -> <<"Macaddr"/utf8>> end. -file("src/postgleam/decode.gleam", 75). ?DOC(" Decode an integer value (int2, int4, int8).\n"). -spec int(gleam@option:option(postgleam@value:value())) -> {ok, integer()} | {error, postgleam@error:error()}. int(Val) -> case Val of {some, {integer, N}} -> {ok, N}; {some, Other} -> {error, {decode_error, <<"Expected Integer, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Integer, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 45). ?DOC( " Decode the element at a given column index using a value decoder.\n" " Designed for use with Gleam's `use` syntax.\n" "\n" " ```gleam\n" " let decoder = {\n" " use id <- decode.element(0, decode.int)\n" " use name <- decode.element(1, decode.text)\n" " decode.success(#(id, name))\n" " }\n" " ```\n" ). -spec element( integer(), fun((gleam@option:option(postgleam@value:value())) -> {ok, HLM} | {error, postgleam@error:error()}), fun((HLM) -> row_decoder(HLO)) ) -> row_decoder(HLO). element(Index, Decoder, Next) -> {row_decoder, fun(Row) -> case list_at(Row, Index) of {ok, Cell} -> case Decoder(Cell) of {ok, Val} -> run(Next(Val), Row); {error, E} -> {error, E} end; {error, _} -> {error, {decode_error, <<<<"Column index "/utf8, (erlang:integer_to_binary(Index))/binary>>/binary, " out of bounds"/utf8>>}} end end}. -file("src/postgleam/decode.gleam", 85). ?DOC(" Decode a text/string value.\n"). -spec text(gleam@option:option(postgleam@value:value())) -> {ok, binary()} | {error, postgleam@error:error()}. text(Val) -> case Val of {some, {text, S}} -> {ok, S}; {some, Other} -> {error, {decode_error, <<"Expected Text, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Text, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 95). ?DOC(" Decode a boolean value.\n"). -spec bool(gleam@option:option(postgleam@value:value())) -> {ok, boolean()} | {error, postgleam@error:error()}. bool(Val) -> case Val of {some, {boolean, B}} -> {ok, B}; {some, Other} -> {error, {decode_error, <<"Expected Boolean, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Boolean, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 107). ?DOC(" Decode a float value (float4, float8).\n"). -spec float(gleam@option:option(postgleam@value:value())) -> {ok, float()} | {error, postgleam@error:error()}. float(Val) -> case Val of {some, {float, F}} -> {ok, F}; {some, Other} -> {error, {decode_error, <<"Expected Float, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Float, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 117). ?DOC(" Decode a bytea (binary data) value.\n"). -spec bytea(gleam@option:option(postgleam@value:value())) -> {ok, bitstring()} | {error, postgleam@error:error()}. bytea(Val) -> case Val of {some, {bytea, B}} -> {ok, B}; {some, Other} -> {error, {decode_error, <<"Expected Bytea, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Bytea, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 127). ?DOC(" Decode a UUID value (16-byte binary).\n"). -spec uuid(gleam@option:option(postgleam@value:value())) -> {ok, bitstring()} | {error, postgleam@error:error()}. uuid(Val) -> case Val of {some, {uuid, U}} -> {ok, U}; {some, Other} -> {error, {decode_error, <<"Expected Uuid, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Uuid, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 137). ?DOC(" Decode a UUID value as a hyphenated string (e.g. \"550e8400-e29b-41d4-a716-446655440000\").\n"). -spec uuid_string(gleam@option:option(postgleam@value:value())) -> {ok, binary()} | {error, postgleam@error:error()}. uuid_string(Val) -> case Val of {some, {uuid, _} = V} -> case postgleam@value:uuid_to_string(V) of {ok, S} -> {ok, S}; {error, _} -> {error, {decode_error, <<"Failed to format UUID as string"/utf8>>}} end; {some, Other} -> {error, {decode_error, <<"Expected Uuid, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Uuid, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 151). ?DOC(" Decode a JSON value (string).\n"). -spec json(gleam@option:option(postgleam@value:value())) -> {ok, binary()} | {error, postgleam@error:error()}. json(Val) -> case Val of {some, {json, S}} -> {ok, S}; {some, Other} -> {error, {decode_error, <<"Expected Json, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Json, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 161). ?DOC(" Decode a JSONB value (string).\n"). -spec jsonb(gleam@option:option(postgleam@value:value())) -> {ok, binary()} | {error, postgleam@error:error()}. jsonb(Val) -> case Val of {some, {jsonb, S}} -> {ok, S}; {some, Other} -> {error, {decode_error, <<"Expected Jsonb, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Jsonb, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 171). ?DOC(" Decode a numeric/decimal value (string representation).\n"). -spec numeric(gleam@option:option(postgleam@value:value())) -> {ok, binary()} | {error, postgleam@error:error()}. numeric(Val) -> case Val of {some, {numeric, N}} -> {ok, N}; {some, Other} -> {error, {decode_error, <<"Expected Numeric, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Numeric, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 183). ?DOC(" Decode a date value (days since 2000-01-01).\n"). -spec date(gleam@option:option(postgleam@value:value())) -> {ok, integer()} | {error, postgleam@error:error()}. date(Val) -> case Val of {some, {date, D}} -> {ok, D}; {some, Other} -> {error, {decode_error, <<"Expected Date, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Date, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 193). ?DOC(" Decode a timestamp value (microseconds since 2000-01-01 00:00:00).\n"). -spec timestamp(gleam@option:option(postgleam@value:value())) -> {ok, integer()} | {error, postgleam@error:error()}. timestamp(Val) -> case Val of {some, {timestamp, T}} -> {ok, T}; {some, Other} -> {error, {decode_error, <<"Expected Timestamp, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Timestamp, got NULL"/utf8>>}} end. -file("src/postgleam/decode.gleam", 205). ?DOC(" Decode a timestamptz value (microseconds since 2000-01-01 00:00:00 UTC).\n"). -spec timestamptz(gleam@option:option(postgleam@value:value())) -> {ok, integer()} | {error, postgleam@error:error()}. timestamptz(Val) -> case Val of {some, {timestamptz, T}} -> {ok, T}; {some, Other} -> {error, {decode_error, <<"Expected Timestamptz, got "/utf8, (value_type_name(Other))/binary>>}}; none -> {error, {decode_error, <<"Expected Timestamptz, got NULL"/utf8>>}} end.