-module(glite@decode). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/glite/decode.gleam"). -export([run/2, success/1, optional/1, dynamic/1, int/1, element/3, float/1, text/1, blob/1, bool/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(GAW) :: {row_decoder, fun((list(glite@value:value())) -> {ok, GAW} | {error, glite@error:error()})}. -file("src/glite/decode.gleam", 30). ?DOC(" Run a decoder on a row.\n"). -spec run(row_decoder(GBA), list(glite@value:value())) -> {ok, GBA} | {error, glite@error:error()}. run(Decoder, Row) -> (erlang:element(2, Decoder))(Row). -file("src/glite/decode.gleam", 57). ?DOC(" Finalize a decoder chain with a value.\n"). -spec success(GBK) -> row_decoder(GBK). success(Value) -> {row_decoder, fun(_) -> {ok, Value} end}. -file("src/glite/decode.gleam", 121). ?DOC( " Make any value decoder nullable (NULL-safe).\n" " Returns `Ok(None)` for NULL, `Ok(Some(val))` for non-NULL.\n" ). -spec optional( fun((glite@value:value()) -> {ok, GBW} | {error, glite@error:error()}) ) -> fun((glite@value:value()) -> {ok, gleam@option:option(GBW)} | {error, glite@error:error()}). optional(Decoder) -> fun(Val) -> case Val of null -> {ok, none}; _ -> case Decoder(Val) of {ok, V} -> {ok, {some, V}}; {error, E} -> {error, E} end end end. -file("src/glite/decode.gleam", 135). ?DOC(" Decode any value as-is (always succeeds, returns the raw Value).\n"). -spec dynamic(glite@value:value()) -> {ok, glite@value:value()} | {error, glite@error:error()}. dynamic(Val) -> {ok, Val}. -file("src/glite/decode.gleam", 143). -spec list_at(list(GCC), integer()) -> {ok, GCC} | {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/glite/decode.gleam", 151). -spec value_type_name(glite@value:value()) -> binary(). value_type_name(Val) -> case Val of null -> <<"Null"/utf8>>; {integer, _} -> <<"Integer"/utf8>>; {real, _} -> <<"Real"/utf8>>; {text, _} -> <<"Text"/utf8>>; {blob, _} -> <<"Blob"/utf8>> end. -file("src/glite/decode.gleam", 66). ?DOC(" Decode an integer value.\n"). -spec int(glite@value:value()) -> {ok, integer()} | {error, glite@error:error()}. int(Val) -> case Val of {integer, N} -> {ok, N}; Other -> {error, {decode_error, <<"Expected Integer, got "/utf8, (value_type_name(Other))/binary>>}} end. -file("src/glite/decode.gleam", 36). ?DOC( " Decode the element at a given column index using a value decoder.\n" " Designed for use with Gleam's `use` syntax.\n" ). -spec element( integer(), fun((glite@value:value()) -> {ok, GBF} | {error, glite@error:error()}), fun((GBF) -> row_decoder(GBH)) ) -> row_decoder(GBH). 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/glite/decode.gleam", 77). ?DOC(" Decode a float value.\n"). -spec float(glite@value:value()) -> {ok, float()} | {error, glite@error:error()}. float(Val) -> case Val of {real, F} -> {ok, F}; Other -> {error, {decode_error, <<"Expected Real, got "/utf8, (value_type_name(Other))/binary>>}} end. -file("src/glite/decode.gleam", 86). ?DOC(" Decode a text/string value.\n"). -spec text(glite@value:value()) -> {ok, binary()} | {error, glite@error:error()}. text(Val) -> case Val of {text, S} -> {ok, S}; Other -> {error, {decode_error, <<"Expected Text, got "/utf8, (value_type_name(Other))/binary>>}} end. -file("src/glite/decode.gleam", 95). ?DOC(" Decode a blob (binary data) value.\n"). -spec blob(glite@value:value()) -> {ok, bitstring()} | {error, glite@error:error()}. blob(Val) -> case Val of {blob, B} -> {ok, B}; Other -> {error, {decode_error, <<"Expected Blob, got "/utf8, (value_type_name(Other))/binary>>}} end. -file("src/glite/decode.gleam", 104). ?DOC(" Decode a boolean value (SQLite stores as Integer 0/1).\n"). -spec bool(glite@value:value()) -> {ok, boolean()} | {error, glite@error:error()}. bool(Val) -> case Val of {integer, 0} -> {ok, false}; {integer, 1} -> {ok, true}; {integer, N} -> {error, {decode_error, <<"Expected Boolean (0 or 1), got Integer "/utf8, (erlang:integer_to_binary(N))/binary>>}}; Other -> {error, {decode_error, <<"Expected Boolean (Integer 0/1), got "/utf8, (value_type_name(Other))/binary>>}} end.