Skip to content

Commit

Permalink
Access user state inside partial to allow streaming output (#100)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeZ99 committed May 16, 2022
1 parent 07e9cc8 commit f680914
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/saxy/partial.ex
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,36 @@ defmodule Saxy.Partial do
end
end

@doc """
Same as partial/2, but continue previous parsing with a new, provided state
as the third argument instead of the previous accumulated state.
i.e.
`Saxy.Partial.parse(partial, binary, new_state) # coninue previous partial with a new state`
This function can return in 3 ways:
* `{:cont, partial}` - The parsing process has not been terminated.
* `{:halt, user_state}` - The parsing process has been terminated, usually because of parser stopping.
* `{:halt, user_state, rest}` - The parsing process has been terminated, usually because of parser halting.
* `{:error, exception}` - The parsing process has erred.
"""
@spec parse(
partial :: t(),
data :: binary,
user_state :: term()
) ::
{:cont, partial :: t()}
| {:halt, state :: term()}
| {:halt, state :: term(), rest :: binary()}
| {:error, exception :: Saxy.ParseError.t()}

def parse(%__MODULE__{} = partial, data, user_state) do
partial = set_user_state(partial, user_state)
parse(partial, data)
end

@doc """
Terminates the XML document parsing.
"""
Expand All @@ -109,4 +139,14 @@ defmodule Saxy.Partial do
{:ok, state.user_state}
end
end

@doc """
Obtain the state set by the user.
"""
@spec get_state(partial :: t()) :: state :: term()
def get_state(%__MODULE__{state: %{user_state: user_state}}), do: user_state

@spec set_user_state(partial :: t(), user_state :: term()) :: partial :: t()
defp set_user_state(%__MODULE__{state: state} = partial, user_state),
do: %{partial | state: %{state | user_state: user_state}}
end

0 comments on commit f680914

Please sign in to comment.