Current section

Files

Jump to
packmatic lib packmatic encoder journaling.ex
Raw

lib/packmatic/encoder/journaling.ex

defmodule Packmatic.Encoder.Journaling do
@moduledoc false
alias Packmatic.Encoder.EncodingState
alias Packmatic.Encoder.JournalingState
alias Packmatic.Encoder.Field
alias Packmatic.Encoder.Event
import :erlang, only: [iolist_size: 1]
defp cont(state), do: {:cont, state}
defp data(state, data), do: {:cont, data, state}
defp done(_, data), do: {:done, data}
@spec journaling_start(EncodingState.t()) ::
{:cont, JournalingState.t()}
@spec journaling_next(JournalingState.t()) ::
{:cont, iodata(), JournalingState.t()}
| {:done, iodata()}
def journaling_start(state) do
cont(%JournalingState{
stream_id: state.stream_id,
remaining: state.encoded,
offset: state.bytes_emitted,
on_event: state.on_event
})
end
def journaling_next(%{current: nil, remaining: [{entry, {:ok, info}} | rest]} = state) do
journaling_next(%{state | current: {entry, info}, remaining: rest})
end
def journaling_next(%{current: nil, remaining: [{_, {:error, _}} | rest]} = state) do
journaling_next(%{state | remaining: rest})
end
def journaling_next(%{current: {entry, info}} = state) do
data = Field.encode_central_file_header(entry, info)
state
|> Map.put(:current, nil)
|> Map.update!(:entries_emitted, &(&1 + 1))
|> Map.update!(:bytes_emitted, &(&1 + iolist_size(data)))
|> data(data)
end
def journaling_next(%{remaining: []} = state) do
data = Field.encode_central_directory_end(state)
state
|> Map.update!(:bytes_emitted, &(&1 + iolist_size(data)))
|> Event.emit_stream_ended(:done)
|> done(data)
end
end