Current section
Files
Jump to
Current section
Files
lib/wildling.ex
defmodule Wildling do
@moduledoc """
Pattern-based string generator.
"""
alias Wildling.Generator
@version "2.0.2"
defstruct generators: [], pattern_count: 0, internal_index: 0
def version, do: @version
@doc """
Create a wildling client (Agent pid) for the given patterns and dictionaries.
"""
def create(patterns, dictionaries \\ %{}) do
dictionaries = dictionaries || %{}
patterns = patterns || []
generators = Enum.map(patterns, &Generator.new(&1, dictionaries))
pattern_count =
Enum.reduce(generators, 0, fn gen, acc -> acc + Generator.count(gen) end)
state = %__MODULE__{
generators: generators,
pattern_count: pattern_count,
internal_index: 0
}
{:ok, pid} = Agent.start_link(fn -> state end)
pid
end
def index(client) when is_pid(client) do
Agent.get(client, & &1.internal_index)
end
def count(client) when is_pid(client) do
Agent.get(client, & &1.pattern_count)
end
def reset(client) when is_pid(client) do
Agent.update(client, fn state -> %{state | internal_index: 0} end)
end
@doc """
Next combination, or `false` when exhausted.
"""
def next(client) when is_pid(client) do
Agent.get_and_update(client, fn state ->
if state.internal_index == state.pattern_count do
{false, state}
else
value = do_get(state, state.internal_index)
{value, %{state | internal_index: state.internal_index + 1}}
end
end)
end
def generators(client) when is_pid(client) do
Agent.get(client, & &1.generators)
end
@doc """
Combination at index, or `false` if out of range.
"""
def get(client, index) when is_pid(client) do
Agent.get(client, &do_get(&1, index))
end
defp do_get(%__MODULE__{} = state, index) do
if index > state.pattern_count - 1 or index < 0 do
false
else
find_in_generators(state.generators, index, 0)
end
end
defp find_in_generators([], _index, _segment), do: false
defp find_in_generators([generator | rest], index, segment_index) do
pattern_index = index - segment_index
if pattern_index < Generator.count(generator) do
Generator.get(generator, pattern_index)
else
find_in_generators(rest, index, segment_index + Generator.count(generator))
end
end
end