Packages

Elixir library to inflect Russian first, last, and middle names.

Current section

Files

Jump to
petrovich_elixir lib petrovich applier.ex
Raw

lib/petrovich/applier.ex

defmodule Petrovich.Applier do
@moduledoc """
Applies rules on value.
This module applies inflection rules on raw values.
It is tightly coupled with `Parser`, which supplies the rules.
This function should not be used directly. Use `Petrovich` module instead.
"""
@rules %{
genitive: 0,
dative: 1,
accusative: 2,
instrumental: 3,
prepositional: 4
}
@doc """
This function applies one of the rule based on case to the name,
making the inflection itself.
These rules should be in format: `%{"mods" => list(5)}`.
"""
@spec apply(String.t(), atom(), map()) :: {atom(), String.t()}
def apply(data, case_, %{"mods" => mods}) do
mod = Enum.at(mods, @rules[case_])
apply_mod(mod, data)
end
defp apply_mod(".", data), do: data
defp apply_mod(mod, data) do
case count_replaces(mod) do
0 -> data <> mod
_ -> replace(mod, data)
end
end
defp replace(mod, data) do
replaces = count_replaces(mod)
length = String.length(data)
root = String.slice(data, 0, length - replaces)
root <> String.replace(mod, "-", "")
end
defp count_replaces(mod) do
mod
|> String.graphemes()
|> Enum.reduce(%{}, fn letter, acc ->
Map.update(acc, letter, 1, &(&1 + 1))
end)
|> Map.get("-", 0)
end
end