-module(kv_sessions@session). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([generate_id/0, id_to_string/1, id_from_string/1, expiry_to_date/1, builder_from/1, builder/0, with_id/2, with_id_string/2, with_expiry/2, with_expires_at/2, with_data/2, with_entry/3, build/1]). -export_type([session_error/0, session_id/0, session/0, expiry/0, session_builder/0]). -type session_error() :: unknown_error | decode_error | db_setup_error | {db_error_insert_error, binary()} | {db_error_get_error, binary()} | {db_error_delete_error, binary()} | {deserialize_error, binary()} | session_expired_error | no_session_error. -opaque session_id() :: {session_id, binary()}. -type session() :: {session, session_id(), {{integer(), integer(), integer()}, {integer(), integer(), integer()}}, gleam@dict:dict(binary(), binary())}. -type expiry() :: {expire_at, birl:time()} | {expire_in, integer()}. -type session_builder() :: {session_builder, session_id(), gleam@option:option(expiry()), gleam@dict:dict(binary(), binary())}. -spec generate_id() -> session_id(). generate_id() -> {session_id, wisp:random_string(200)}. -spec id_to_string(session_id()) -> binary(). id_to_string(Id) -> case Id of {session_id, Id_string} -> Id_string end. -spec id_from_string(binary()) -> session_id(). id_from_string(Id) -> {session_id, Id}. -spec expiry_to_date(expiry()) -> {{integer(), integer(), integer()}, {integer(), integer(), integer()}}. expiry_to_date(Expiry) -> _pipe@1 = case Expiry of {expire_at, Time} -> Time; {expire_in, Seconds} -> _pipe = birl:now(), birl:add(_pipe, birl@duration:seconds(Seconds)) end, birl:to_erlang_universal_datetime(_pipe@1). -spec builder_from(session()) -> session_builder(). builder_from(Session) -> {session_builder, erlang:element(2, Session), {some, {expire_at, birl:from_erlang_universal_datetime(erlang:element(3, Session))}}, erlang:element(4, Session)}. -spec builder() -> session_builder(). builder() -> {session_builder, generate_id(), none, gleam@dict:new()}. -spec with_id(session_builder(), session_id()) -> session_builder(). with_id(Session, Id) -> erlang:setelement(2, Session, Id). -spec with_id_string(session_builder(), binary()) -> session_builder(). with_id_string(Session, Id) -> erlang:setelement(2, Session, {session_id, Id}). -spec with_expiry(session_builder(), expiry()) -> session_builder(). with_expiry(Session, Expiry) -> erlang:setelement(3, Session, {some, Expiry}). -spec with_expires_at(session_builder(), birl:time()) -> session_builder(). with_expires_at(Session, Expires_at) -> erlang:setelement(3, Session, {some, {expire_at, Expires_at}}). -spec with_data(session_builder(), gleam@dict:dict(binary(), binary())) -> session_builder(). with_data(Session, Data) -> erlang:setelement(4, Session, Data). -spec with_entry(session_builder(), binary(), binary()) -> session_builder(). with_entry(Session, Key, Data) -> erlang:setelement( 4, Session, gleam@dict:insert(erlang:element(4, Session), Key, Data) ). -spec build(session_builder()) -> session(). build(Session) -> Expiry = gleam@option:unwrap( erlang:element(3, Session), {expire_in, 60 * 60} ), {session, erlang:element(2, Session), expiry_to_date(Expiry), erlang:element(4, Session)}.