Skip to main content

src/packkit@recipe.erl

-module(packkit@recipe).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/packkit/recipe.gleam").
-export([archive_only/1, wrap/2, archive_with/2, tar_gzip/0, tar_zlib/0, tar_lz4/0, tar_snappy/0, tar_bzip2/0, tar_xz/0, tar_zstd/0, tar_lzw/0, tar_brotli/0, cpio_gzip/0, cpio_bzip2/0, cpio_xz/0, cpio_zstd/0, tar/0, zip/0, seven_z/0, ar/0, cpio/0, archive_format/1, codecs/1, outermost_codec/1, description/1]).
-export_type([recipe/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.

-opaque recipe() :: {recipe,
        packkit@archive:archive_format(),
        list(packkit@codec:codec())}.

-file("src/packkit/recipe.gleam", 20).
?DOC(" Create a recipe that carries an archive but no outer codec yet.\n").
-spec archive_only(packkit@archive:archive_format()) -> recipe().
archive_only(Format) ->
    {recipe, Format, []}.

-file("src/packkit/recipe.gleam", 34).
?DOC(
    " Wrap an existing recipe in one more outer codec.  O(1) thanks to\n"
    " the reversed internal codec list.\n"
).
-spec wrap(recipe(), packkit@codec:codec()) -> recipe().
wrap(Recipe, Outer_codec) ->
    {recipe,
        erlang:element(2, Recipe),
        [Outer_codec | erlang:element(3, Recipe)]}.

-file("src/packkit/recipe.gleam", 25).
?DOC(" Create a recipe with an archive and one outer codec.\n").
-spec archive_with(packkit@archive:archive_format(), packkit@codec:codec()) -> recipe().
archive_with(Format, Wrapped_by) ->
    _pipe = archive_only(Format),
    wrap(_pipe, Wrapped_by).

-file("src/packkit/recipe.gleam", 39).
?DOC(" Convenience constructor for `tar.gz`.\n").
-spec tar_gzip() -> recipe().
tar_gzip() ->
    archive_with(packkit@archive:tar(), packkit@codec:gzip()).

-file("src/packkit/recipe.gleam", 44).
?DOC(" Convenience constructor for `tar.zlib`.\n").
-spec tar_zlib() -> recipe().
tar_zlib() ->
    archive_with(packkit@archive:tar(), packkit@codec:zlib()).

-file("src/packkit/recipe.gleam", 49).
?DOC(" Convenience constructor for `tar.lz4`.\n").
-spec tar_lz4() -> recipe().
tar_lz4() ->
    archive_with(packkit@archive:tar(), packkit@codec:lz4()).

-file("src/packkit/recipe.gleam", 54).
?DOC(" Convenience constructor for `tar.snappy`.\n").
-spec tar_snappy() -> recipe().
tar_snappy() ->
    archive_with(packkit@archive:tar(), packkit@codec:snappy()).

-file("src/packkit/recipe.gleam", 59).
?DOC(" Convenience constructor for `tar.bz2`.\n").
-spec tar_bzip2() -> recipe().
tar_bzip2() ->
    archive_with(packkit@archive:tar(), packkit@codec:bzip2()).

-file("src/packkit/recipe.gleam", 64).
?DOC(" Convenience constructor for `tar.xz`.\n").
-spec tar_xz() -> recipe().
tar_xz() ->
    archive_with(packkit@archive:tar(), packkit@codec:xz()).

-file("src/packkit/recipe.gleam", 69).
?DOC(" Convenience constructor for `tar.zst`.\n").
-spec tar_zstd() -> recipe().
tar_zstd() ->
    archive_with(packkit@archive:tar(), packkit@codec:zstd()).

-file("src/packkit/recipe.gleam", 74).
?DOC(" Convenience constructor for `tar.Z` (Unix compress / LZW).\n").
-spec tar_lzw() -> recipe().
tar_lzw() ->
    archive_with(packkit@archive:tar(), packkit@codec:lzw()).

-file("src/packkit/recipe.gleam", 82).
?DOC(
    " Convenience constructor for `tar.br`.  Round-trips end-to-end via\n"
    " brotli's uncompressed-metablock encoder; the bytes are valid for\n"
    " any conforming brotli decoder but do no actual LZ77/Huffman\n"
    " compression yet.\n"
).
-spec tar_brotli() -> recipe().
tar_brotli() ->
    archive_with(packkit@archive:tar(), packkit@codec:brotli()).

-file("src/packkit/recipe.gleam", 87).
?DOC(" Convenience constructor for `cpio.gz`.\n").
-spec cpio_gzip() -> recipe().
cpio_gzip() ->
    archive_with(packkit@archive:cpio_newc(), packkit@codec:gzip()).

-file("src/packkit/recipe.gleam", 92).
?DOC(" `cpio.bz2` recipe — cpio body, bzip2-compressed envelope.\n").
-spec cpio_bzip2() -> recipe().
cpio_bzip2() ->
    archive_with(packkit@archive:cpio_newc(), packkit@codec:bzip2()).

-file("src/packkit/recipe.gleam", 97).
?DOC(" `cpio.xz` recipe — cpio body, xz-compressed envelope.\n").
-spec cpio_xz() -> recipe().
cpio_xz() ->
    archive_with(packkit@archive:cpio_newc(), packkit@codec:xz()).

-file("src/packkit/recipe.gleam", 102).
?DOC(" `cpio.zst` recipe — cpio body, zstd-compressed envelope.\n").
-spec cpio_zstd() -> recipe().
cpio_zstd() ->
    archive_with(packkit@archive:cpio_newc(), packkit@codec:zstd()).

-file("src/packkit/recipe.gleam", 111).
?DOC(
    " Convenience constructor for a bare `tar` archive (no outer codec).\n"
    " Equivalent to `archive_only(format: archive.tar())`; provided so\n"
    " the same `packkit.pack` / `packkit.unpack` entrypoints serve both\n"
    " uncompressed tar and codec-wrapped tar without the caller switching\n"
    " to `packkit.write` / `packkit.read`.\n"
).
-spec tar() -> recipe().
tar() ->
    archive_only(packkit@archive:tar()).

-file("src/packkit/recipe.gleam", 120).
?DOC(
    " Convenience constructor for a bare ZIP archive.  ZIP carries its\n"
    " own per-entry compression internally, so there's no recipe-level\n"
    " codec to wrap it in — but exposing `recipe.zip()` lets callers use\n"
    " the same `packkit.pack` / `packkit.unpack` API they use for tar\n"
    " recipes, instead of switching to `packkit.write` / `packkit.read`.\n"
).
-spec zip() -> recipe().
zip() ->
    archive_only(packkit@archive:zip()).

-file("src/packkit/recipe.gleam", 128).
?DOC(
    " Convenience constructor for a bare 7z archive.  Like ZIP, 7z\n"
    " applies its own internal compression and does not take a recipe\n"
    " codec wrapper; this constructor keeps the API symmetric across\n"
    " archive families.\n"
).
-spec seven_z() -> recipe().
seven_z() ->
    archive_only(packkit@archive:seven_z()).

-file("src/packkit/recipe.gleam", 134).
?DOC(
    " Convenience constructor for a bare `ar` archive (BSD long-name\n"
    " format on encode; GNU string-table form also accepted on decode).\n"
).
-spec ar() -> recipe().
ar() ->
    archive_only(packkit@archive:ar()).

-file("src/packkit/recipe.gleam", 139).
?DOC(" Convenience constructor for a bare cpio (newc) archive.\n").
-spec cpio() -> recipe().
cpio() ->
    archive_only(packkit@archive:cpio_newc()).

-file("src/packkit/recipe.gleam", 144).
?DOC(" Read the archive format the recipe was constructed with.\n").
-spec archive_format(recipe()) -> packkit@archive:archive_format().
archive_format(Recipe) ->
    erlang:element(2, Recipe).

-file("src/packkit/recipe.gleam", 149).
?DOC(" Read the codec chain in inner-to-outer order.\n").
-spec codecs(recipe()) -> list(packkit@codec:codec()).
codecs(Recipe) ->
    lists:reverse(erlang:element(3, Recipe)).

-file("src/packkit/recipe.gleam", 154).
?DOC(" Read the outermost codec, if any.\n").
-spec outermost_codec(recipe()) -> gleam@option:option(packkit@codec:codec()).
outermost_codec(Recipe) ->
    case erlang:element(3, Recipe) of
        [Head | _] ->
            {some, Head};

        [] ->
            none
    end.

-file("src/packkit/recipe.gleam", 162).
?DOC(" Human-readable canonical description for debugging and tests.\n").
-spec description(recipe()) -> binary().
description(Recipe) ->
    _pipe = [packkit@archive:name(erlang:element(2, Recipe)) |
        gleam@list:map(codecs(Recipe), fun packkit@codec:name/1)],
    gleam@string:join(_pipe, <<"."/utf8>>).