-module(storail). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([key/2, namespaced_key/3, write/2, read/1, delete/1, read_namespace/2]). -export_type([config/0, collection/1, key/1, storail_error/0]). -type config() :: {config, binary(), binary()}. -type collection(HPX) :: {collection, binary(), fun((HPX) -> gleam@json:json()), decode@zero:decoder(HPX), config()}. -type key(HPY) :: {key, collection(HPY), list(binary()), binary()}. -type storail_error() :: {object_not_found, list(binary()), binary()} | {corrupt_json, binary(), gleam@json:decode_error()} | {file_system_error, binary(), simplifile:file_error()}. -file("/Users/louis/src/gleam/storail/src/storail.gleam", 87). -spec key(collection(HPZ), binary()) -> key(HPZ). key(Collection, Id) -> {key, Collection, [], Id}. -file("/Users/louis/src/gleam/storail/src/storail.gleam", 91). -spec namespaced_key(collection(HQC), list(binary()), binary()) -> key(HQC). namespaced_key(Collection, Namespace, Id) -> {key, Collection, Namespace, Id}. -file("/Users/louis/src/gleam/storail/src/storail.gleam", 108). -spec namespace_path(collection(any()), list(binary())) -> binary(). namespace_path(Collection, Namespace) -> _pipe = erlang:element(2, erlang:element(5, Collection)), _pipe@1 = filepath:join(_pipe, erlang:element(2, Collection)), gleam@list:fold(Namespace, _pipe@1, fun filepath:join/2). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 114). -spec object_data_path(key(any())) -> binary(). object_data_path(Key) -> _pipe = namespace_path(erlang:element(2, Key), erlang:element(3, Key)), filepath:join(_pipe, <<(erlang:element(4, Key))/binary, ".json"/utf8>>). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 119). -spec object_tmp_path(key(any())) -> binary(). object_tmp_path(Key) -> Random_component = begin _pipe = crypto:strong_rand_bytes(16), _pipe@1 = gleam@bit_array:base64_url_encode(_pipe, false), gleam@string:slice(_pipe@1, 0, 16) end, Name = <<<<<<<<<<(erlang:element(2, erlang:element(2, Key)))/binary, "-"/utf8>>/binary, (erlang:element(4, Key))/binary>>/binary, "-"/utf8>>/binary, Random_component/binary>>/binary, ".json"/utf8>>, _pipe@2 = erlang:element(3, erlang:element(5, erlang:element(2, Key))), filepath:join(_pipe@2, Name). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 130). -spec ensure_parent_directory_exists(binary()) -> {ok, nil} | {error, storail_error()}. ensure_parent_directory_exists(Path) -> _pipe = Path, _pipe@1 = filepath:directory_name(_pipe), _pipe@2 = simplifile:create_directory_all(_pipe@1), gleam@result:map_error( _pipe@2, fun(_capture) -> {file_system_error, Path, _capture} end ). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 155). -spec write(key(HQP), HQP) -> {ok, nil} | {error, storail_error()}. write(Key, Data) -> Tmp_path = object_tmp_path(Key), Data_path = object_data_path(Key), gleam@result:'try'( ensure_parent_directory_exists(Tmp_path), fun(_) -> gleam@result:'try'( ensure_parent_directory_exists(Data_path), fun(_) -> Json = begin _pipe = Data, _pipe@1 = (erlang:element(3, erlang:element(2, Key)))( _pipe ), gleam@json:to_string(_pipe@1) end, gleam@result:'try'( begin _pipe@2 = simplifile:write(Tmp_path, Json), gleam@result:map_error( _pipe@2, fun(_capture) -> {file_system_error, Tmp_path, _capture} end ) end, fun(_) -> gleam@result:'try'( begin _pipe@3 = simplifile_erl:rename_file( Tmp_path, Data_path ), gleam@result:map_error( _pipe@3, fun(_capture@1) -> {file_system_error, Data_path, _capture@1} end ) end, fun(_) -> {ok, nil} end ) end ) end ) end ). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 182). -spec read_file(binary(), list(binary()), binary()) -> {ok, bitstring()} | {error, storail_error()}. read_file(Path, Namespace, Id) -> _pipe = simplifile_erl:read_bits(Path), gleam@result:map_error(_pipe, fun(Error) -> case Error of enoent -> {object_not_found, Namespace, Id}; _ -> {file_system_error, Path, Error} end end). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 196). -spec parse_json(bitstring(), binary(), decode@zero:decoder(HQW)) -> {ok, HQW} | {error, storail_error()}. parse_json(Json, Path, Decoder) -> case gleam@json:decode_bits( Json, fun(_capture) -> decode@zero:run(_capture, Decoder) end ) of {ok, D} -> {ok, D}; {error, E} -> {error, {corrupt_json, Path, E}} end. -file("/Users/louis/src/gleam/storail/src/storail.gleam", 218). -spec read(key(HRA)) -> {ok, HRA} | {error, storail_error()}. read(Key) -> Path = object_data_path(Key), gleam@result:'try'( read_file(Path, erlang:element(3, Key), erlang:element(4, Key)), fun(Json) -> parse_json(Json, Path, erlang:element(4, erlang:element(2, Key))) end ). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 235). -spec delete(key(any())) -> {ok, nil} | {error, storail_error()}. delete(Key) -> Path = object_data_path(Key), _pipe = simplifile:delete_all([Path]), gleam@result:map_error( _pipe, fun(_capture) -> {file_system_error, Path, _capture} end ). -file("/Users/louis/src/gleam/storail/src/storail.gleam", 255). -spec read_namespace(collection(HRI), list(binary())) -> {ok, gleam@dict:dict(binary(), HRI)} | {error, storail_error()}. read_namespace(Collection, Namespace) -> Path = namespace_path(Collection, Namespace), case simplifile_erl:read_directory(Path) of {error, E} -> case E of enoent -> {ok, gleam@dict:new()}; _ -> {error, {file_system_error, Path, E}} end; {ok, Contents} -> _pipe = Contents, _pipe@1 = gleam@list:filter( _pipe, fun(_capture) -> gleam@string:ends_with(_capture, <<".json"/utf8>>) end ), _pipe@3 = gleam@list:try_map( _pipe@1, fun(Filename) -> Id = begin _pipe@2 = Filename, gleam@string:drop_right(_pipe@2, 5) end, Path@1 = filepath:join(Path, Filename), gleam@result:'try'( read_file(Path@1, Namespace, Id), fun(Json) -> gleam@result:map( parse_json( Json, Path@1, erlang:element(4, Collection) ), fun(Data) -> {Id, Data} end ) end ) end ), gleam@result:map(_pipe@3, fun maps:from_list/1) end.