-module(oaspec@codegen@writer). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/oaspec/codegen/writer.gleam"). -export([write_all/3, generate_all/2, resolve_paths/2, output_dirs/1, error_to_string/1]). -export_type([write_error/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type write_error() :: {directory_create_error, binary(), binary()} | {file_write_error, binary(), binary()}. -file("src/oaspec/codegen/writer.gleam", 67). ?DOC(" Ensure a directory exists, creating it if necessary.\n"). -spec ensure_directory(binary()) -> {ok, nil} | {error, write_error()}. ensure_directory(Path) -> _pipe = simplifile:create_directory_all(Path), gleam@result:map_error( _pipe, fun(_) -> {directory_create_error, Path, <<"Failed to create directory"/utf8>>} end ). -file("src/oaspec/codegen/writer.gleam", 75). ?DOC(" Write a list of generated files to a directory.\n"). -spec write_files( list(oaspec@codegen@context:generated_file()), binary(), list(binary()), fun((binary()) -> nil) ) -> {ok, list(binary())} | {error, write_error()}. write_files(Files, Base_path, Written, On_write) -> gleam@list:try_fold( Files, Written, fun(Acc, File) -> Full_path = <<<>/binary, (erlang:element(2, File))/binary>>, gleam@result:'try'( begin _pipe = simplifile:write(Full_path, erlang:element(3, File)), gleam@result:map_error( _pipe, fun(_) -> {file_write_error, Full_path, <<"Failed to write file"/utf8>>} end ) end, fun(_) -> On_write(Full_path), {ok, [Full_path | Acc]} end ) end ). -file("src/oaspec/codegen/writer.gleam", 24). ?DOC(" Write pre-generated files to disk based on configuration.\n"). -spec write_all( list(oaspec@codegen@context:generated_file()), oaspec@config:config(), fun((binary()) -> nil) ) -> {ok, list(binary())} | {error, write_error()}. write_all(Files, Cfg, On_write) -> Shared_files = gleam@list:filter( Files, fun(F) -> erlang:element(4, F) =:= shared_target end ), Server_files = gleam@list:filter( Files, fun(F@1) -> erlang:element(4, F@1) =:= server_target end ), Client_files = gleam@list:filter( Files, fun(F@2) -> erlang:element(4, F@2) =:= client_target end ), Server_path = erlang:element(3, Cfg), Client_path = erlang:element(4, Cfg), Written_files = [], gleam@result:'try'(case erlang:element(6, Cfg) of server -> gleam@result:'try'( ensure_directory(Server_path), fun(_) -> _pipe = write_files( Shared_files, Server_path, Written_files, On_write ), gleam@result:'try'( _pipe, fun(W) -> write_files( Server_files, Server_path, W, On_write ) end ) end ); both -> gleam@result:'try'( ensure_directory(Server_path), fun(_) -> _pipe = write_files( Shared_files, Server_path, Written_files, On_write ), gleam@result:'try'( _pipe, fun(W) -> write_files( Server_files, Server_path, W, On_write ) end ) end ); client -> {ok, Written_files} end, fun(Written_files@1) -> gleam@result:'try'(case erlang:element(6, Cfg) of client -> gleam@result:'try'( ensure_directory(Client_path), fun(_) -> _pipe@1 = write_files( Shared_files, Client_path, Written_files@1, On_write ), gleam@result:'try'( _pipe@1, fun(W@1) -> write_files( Client_files, Client_path, W@1, On_write ) end ) end ); both -> gleam@result:'try'( ensure_directory(Client_path), fun(_) -> _pipe@1 = write_files( Shared_files, Client_path, Written_files@1, On_write ), gleam@result:'try'( _pipe@1, fun(W@1) -> write_files( Client_files, Client_path, W@1, On_write ) end ) end ); server -> {ok, Written_files@1} end, fun(Written_files@2) -> {ok, Written_files@2} end) end). -file("src/oaspec/codegen/writer.gleam", 15). ?DOC(" Generate and write all files based on configuration.\n"). -spec generate_all(oaspec@codegen@context:context(), fun((binary()) -> nil)) -> {ok, list(binary())} | {error, write_error()}. generate_all(Ctx, On_write) -> Files = oaspec@generate:generate_all_files(Ctx), write_all(Files, erlang:element(3, Ctx), On_write). -file("src/oaspec/codegen/writer.gleam", 96). ?DOC( " Resolve generated files to their full output paths and content.\n" " Used by --check to compare against existing files without writing.\n" ). -spec resolve_paths( list(oaspec@codegen@context:generated_file()), oaspec@config:config() ) -> list({binary(), binary()}). resolve_paths(Files, Cfg) -> Shared_files = gleam@list:filter( Files, fun(F) -> erlang:element(4, F) =:= shared_target end ), Server_files = gleam@list:filter( Files, fun(F@1) -> erlang:element(4, F@1) =:= server_target end ), Client_files = gleam@list:filter( Files, fun(F@2) -> erlang:element(4, F@2) =:= client_target end ), Server_path = erlang:element(3, Cfg), Client_path = erlang:element(4, Cfg), Server_entries = case erlang:element(6, Cfg) of server -> gleam@list:map( lists:append(Shared_files, Server_files), fun(F@3) -> {<<<>/binary, (erlang:element(2, F@3))/binary>>, erlang:element(3, F@3)} end ); both -> gleam@list:map( lists:append(Shared_files, Server_files), fun(F@3) -> {<<<>/binary, (erlang:element(2, F@3))/binary>>, erlang:element(3, F@3)} end ); client -> [] end, Client_entries = case erlang:element(6, Cfg) of client -> gleam@list:map( lists:append(Shared_files, Client_files), fun(F@4) -> {<<<>/binary, (erlang:element(2, F@4))/binary>>, erlang:element(3, F@4)} end ); both -> gleam@list:map( lists:append(Shared_files, Client_files), fun(F@4) -> {<<<>/binary, (erlang:element(2, F@4))/binary>>, erlang:element(3, F@4)} end ); server -> [] end, lists:append(Server_entries, Client_entries). -file("src/oaspec/codegen/writer.gleam", 130). ?DOC(" Return the output directories that would be written to for the given config.\n"). -spec output_dirs(oaspec@config:config()) -> list(binary()). output_dirs(Cfg) -> case erlang:element(6, Cfg) of server -> [erlang:element(3, Cfg)]; client -> [erlang:element(4, Cfg)]; both -> [erlang:element(3, Cfg), erlang:element(4, Cfg)] end. -file("src/oaspec/codegen/writer.gleam", 139). ?DOC(" Convert a write error to a human-readable string.\n"). -spec error_to_string(write_error()) -> binary(). error_to_string(Error) -> case Error of {directory_create_error, Path, Detail} -> <<<<<<"Failed to create directory "/utf8, Path/binary>>/binary, ": "/utf8>>/binary, Detail/binary>>; {file_write_error, Path@1, Detail@1} -> <<<<<<"Failed to write file "/utf8, Path@1/binary>>/binary, ": "/utf8>>/binary, Detail@1/binary>> end.