-module(bravo@bag). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([new/3, insert/2, lookup/2, delete/1, delete_key/2, delete_all_objects/1, delete_object/2, tab2file/5, tab2list/1, file2tab/3, insert_new/2, take/2, member/2, first/1, last/1, next/2, prev/2]). -export_type([bag/1]). -opaque bag(GUX) :: {bag, gleam@erlang@atom:atom_(), integer()} | {gleam_phantom, GUX}. -spec new(binary(), integer(), bravo:access()) -> {ok, bag(any())} | {error, bravo:bravo_error()}. new(Name, Keypos, Access) -> Atom = erlang:binary_to_atom(Name), gleam@bool:guard( Keypos < 1, {error, non_positive_keypos}, fun() -> gleam@result:'try'(bravo_ffi:try_new(Atom, [bag, case Access of public -> public; protected -> protected; private -> private end, named_table, {keypos, Keypos}, {write_concurrency, auto}, {read_concurrency, true}, {decentralized_counters, true}]), fun(A) -> {ok, {bag, A, Keypos}} end) end ). -spec insert(bag(GVC), list(GVC)) -> boolean(). insert(Bag, Objects) -> gleam@bool:guard( gleam@list:is_empty(Objects), false, fun() -> bravo_ffi:try_insert( erlang:element(2, Bag), erlang:element(3, Bag), Objects ) end ). -spec lookup(bag(GVF), any()) -> list(GVF). lookup(Bag, Key) -> bravo_ffi:try_lookup(erlang:element(2, Bag), Key). -spec delete(bag(any())) -> boolean(). delete(Bag) -> bravo_ffi:try_delete(erlang:element(2, Bag)). -spec delete_key(bag(any()), any()) -> nil. delete_key(Bag, Key) -> bravo_ffi:try_delete_key(erlang:element(2, Bag), Key), nil. -spec delete_all_objects(bag(any())) -> nil. delete_all_objects(Bag) -> bravo_ffi:try_delete_all_objects(erlang:element(2, Bag)), nil. -spec delete_object(bag(GVQ), GVQ) -> nil. delete_object(Bag, Object) -> bravo_ffi:try_delete_object(erlang:element(2, Bag), Object), nil. -spec tab2file(bag(any()), binary(), boolean(), boolean(), boolean()) -> {ok, nil} | {error, bravo:bravo_error()}. tab2file(Bag, Filename, Object_count, Md5sum, Sync) -> bravo_ffi:try_tab2file( erlang:element(2, Bag), gleam@string:to_utf_codepoints(Filename), Object_count, Md5sum, Sync ). -spec tab2list(bag(GWD)) -> list(GWD). tab2list(Bag) -> bravo_ffi:try_tab2list(erlang:element(2, Bag)). -spec file2tab( binary(), boolean(), fun((gleam@dynamic:dynamic_()) -> {ok, GVW} | {error, any()}) ) -> {ok, bag(GVW)} | {error, bravo:bravo_error()}. file2tab(Filename, Verify, Decoder) -> gleam@result:'try'( bravo_ffi:try_file2tab(gleam@string:to_utf_codepoints(Filename), Verify), fun(Name) -> _assert_subject = gleam@dynamic:int( bravo_ffi:inform(Name, erlang:binary_to_atom(<<"keypos"/utf8>>)) ), {ok, Keypos} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"bravo/bag"/utf8>>, function => <<"file2tab"/utf8>>, line => 151}) end, Table = {bag, Name, Keypos}, gleam@list:map( tab2list(Table), fun(Obj) -> delete_object(Table, Obj), case erlang:tuple_size(Obj) of 1 -> insert(Table, [erlang:element(1, Obj)]); _ -> insert(Table, [Obj]) end end ), gleam@bool:guard( (gleam@list:all(tab2list(Table), fun(Obj@1) -> _pipe = Obj@1, _pipe@1 = gleam@dynamic:from(_pipe), _pipe@2 = Decoder(_pipe@1), gleam@result:is_ok(_pipe@2) end)), {ok, Table}, fun() -> delete(Table), {error, decode_failure} end ) end ). -spec insert_new(bag(GWG), list(GWG)) -> boolean(). insert_new(Bag, Objects) -> gleam@bool:guard( gleam@list:is_empty(Objects), false, fun() -> bravo_ffi:try_insert_new( erlang:element(2, Bag), erlang:element(3, Bag), Objects ) end ). -spec take(bag(GWJ), any()) -> list(GWJ). take(Bag, Key) -> bravo_ffi:try_take(erlang:element(2, Bag), Key). -spec member(bag(any()), any()) -> boolean(). member(Bag, Key) -> bravo_ffi:try_member(erlang:element(2, Bag), Key). -spec first(bag(any())) -> gleam@option:option(any()). first(Bag) -> bravo_ffi:try_first(erlang:element(2, Bag)). -spec last(bag(any())) -> gleam@option:option(any()). last(Bag) -> bravo_ffi:try_last(erlang:element(2, Bag)). -spec next(bag(any()), GXA) -> gleam@option:option(GXA). next(Bag, Key) -> bravo_ffi:try_next(erlang:element(2, Bag), Key). -spec prev(bag(any()), GXE) -> gleam@option:option(GXE). prev(Bag, Key) -> bravo_ffi:try_prev(erlang:element(2, Bag), Key).