Skip to content

Commit

Permalink
Updates elixir version
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Jul 2, 2019
1 parent 56a5aee commit 8a55771
Show file tree
Hide file tree
Showing 19 changed files with 130 additions and 135 deletions.
4 changes: 4 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"],
line_length: 79
]
12 changes: 8 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ language: elixir
sudo: false

elixir:
- 1.4
- 1.6
- 1.7
- 1.8
- 1.9

otp_release:
- 18.2
- 19.3
- 20.0
- 21.0

env: MIX_ENV=test

script:
- mix coveralls.travis
- mix format --check-formatted
- mix credo --strict
- mix coveralls.travis

notifications:
email: false
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## Version 1.0.0

### Breaking changes

- Now only support `elixir>=1.6`

### Features

- Updates dependencies

### Misc

- Adds `dependabot`
- Adds `mix format`


## Version 0.1.2

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

Please, make sure that all these commands succeed before pushing anything:

0. `mix format`
1. `mix test`
2. `mix credo --strict`
3. `mix dialyzer` (it may take long on the first run)
Expand Down
32 changes: 3 additions & 29 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,6 @@
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for
# 3rd-party users, it should be done in your "mix.exs" file.

# You can configure for your application as:
#
# config :petrovich_elixir, key: :value
#
# And access this configuration in your application as:
#
# Application.get_env(:petrovich_elixir, :key)
#
# Or configure a 3rd-party app:
#
# config :logger, level: :info
#

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"

if Mix.env == :test, do: import_config "test.exs"
if Mix.env == :dev, do: import_config "dev.exs"
# We only use config for tests and development:
if Mix.env() == :test, do: import_config("test.exs")
if Mix.env() == :dev, do: import_config("dev.exs")
9 changes: 5 additions & 4 deletions lib/petrovich/applier.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule Petrovich.Applier do
dative: 1,
accusative: 2,
instrumental: 3,
prepositional: 4,
prepositional: 4
}

@doc """
Expand All @@ -22,13 +22,14 @@ defmodule Petrovich.Applier do
These rules should be in format: `%{"mods" => list(5)}`.
"""
@spec apply(String.t, atom(), map()) :: {atom(), String.t}
@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
Expand All @@ -46,8 +47,8 @@ defmodule Petrovich.Applier do

defp count_replaces(mod) do
mod
|> String.graphemes
|> Enum.reduce(%{}, fn(letter, acc) ->
|> String.graphemes()
|> Enum.reduce(%{}, fn letter, acc ->
Map.update(acc, letter, 1, &(&1 + 1))
end)
|> Map.get("-", 0)
Expand Down
20 changes: 10 additions & 10 deletions lib/petrovich/detector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ defmodule Petrovich.Detector do
:error
"""
@spec detect_gender(String.t, atom()) :: {:ok, String.t} | :error
@spec detect_gender(String.t(), atom()) :: {:ok, String.t()} | :error
def detect_gender(name, type) do
%{"exceptions" => exceptions,
"suffixes" => suffixes} = GenderStore.get("gender", to_string(type))
%{"exceptions" => exceptions, "suffixes" => suffixes} =
GenderStore.get("gender", to_string(type))

name
|> String.downcase
|> String.downcase()
|> String.split("-")
|> Enum.map(fn(item) -> prepare_value(item, exceptions, suffixes) end)
|> Enum.map(fn item -> prepare_value(item, exceptions, suffixes) end)
|> ResultJoiner.join_any_results(&join_result/1)
end

Expand All @@ -53,7 +53,7 @@ defmodule Petrovich.Detector do

defp join_result(result) do
result
|> Enum.find(fn (item) ->
|> Enum.find(fn item ->
case item do
{:ok, _} -> true
_ -> false
Expand All @@ -64,17 +64,18 @@ defmodule Petrovich.Detector do

defp maybe_exception(name, exceptions) do
exceptions
|> Enum.find(fn({_, names}) -> name in names end)
|> Enum.find(fn {_, names} -> name in names end)
|> case do
{gender, _} -> {:ok, gender}
nil -> {:error, name}
end
end

defp maybe_rule({:ok, gender}, _), do: {:ok, gender}

defp maybe_rule({:error, name}, suffixes) do
suffixes
|> Enum.find(fn({_, rule}) -> fits?(name, rule) end)
|> Enum.find(fn {_, rule} -> fits?(name, rule) end)
|> case do
{gender, _} -> {:ok, gender}
nil -> :error
Expand All @@ -84,10 +85,9 @@ defmodule Petrovich.Detector do
defp fits?(name, rule) do
name_len = String.length(name)

Enum.any?(rule, fn(test) ->
Enum.any?(rule, fn test ->
test_len = String.length(test)
test == String.slice(name, name_len - test_len, test_len)
end)
end

end
39 changes: 21 additions & 18 deletions lib/petrovich/parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ defmodule Petrovich.Parser do
{:ok, "Пироговым"}
"""
@spec parse(String.t, atom(),
atom(), atom() | nil) :: {:ok, String.t} | :error
@spec parse(String.t(), atom(), atom(), atom() | nil) ::
{:ok, String.t()} | :error
def parse(data, _, :nomenative, _), do: {:ok, data}

def parse(data, type, case_, gender) do
gender = maybe_detect_gender(gender, data, type)
apply_rule(data, to_string(type), case_, to_string(gender))
Expand All @@ -46,7 +47,7 @@ defmodule Petrovich.Parser do
"Пироговым"
"""
@spec parse!(String.t, atom(), atom(), atom() | nil) :: String.t
@spec parse!(String.t(), atom(), atom(), atom() | nil) :: String.t()
def parse!(data, type, case_, gender) do
case parse(data, type, case_, gender) do
{:ok, value} -> value
Expand All @@ -56,66 +57,68 @@ defmodule Petrovich.Parser do

defp maybe_detect_gender(gender, data, type) do
with nil <- gender,
{:ok, parsed_gender} <- Detector.detect_gender(data, type) do
parsed_gender
{:ok, parsed_gender} <- Detector.detect_gender(data, type) do
parsed_gender
else
:error -> :androgynous
_ -> gender
end
end

defp apply_rule(values, type, case_, gender) do
%{"exceptions" => exceptions,
"suffixes" => suffixes} = NameStore.get(type)
%{"exceptions" => exceptions, "suffixes" => suffixes} = NameStore.get(type)

values
|> String.split("-")
|> Enum.map(fn(item) ->
|> Enum.map(fn item ->
prepare_value(item, case_, gender, exceptions, suffixes)
end)
|> ResultJoiner.join_all_results(&join_callback/1)
end

defp prepare_value(value, case_, gender, exceptions, suffixes) do
value
|> String.downcase
|> String.downcase()
|> maybe_exception(gender, exceptions)
|> maybe_rule(gender, suffixes)
|> case do
{:error, _} -> :error
{:ok, res} -> {:ok, Applier.apply(value, case_, res)}
{:ok, res} -> {:ok, Applier.apply(value, case_, res)}
end
end

defp join_callback(results) do
results
|> Enum.map(fn({_, item}) -> item end)
|> Enum.map(fn {_, item} -> item end)
|> Enum.join("-")
end

defp maybe_exception(name, gender, exceptions) do
exceptions
|> Enum.filter(fn(item) -> fits?(:e, name, gender, item) end)
|> Enum.filter(fn item -> fits?(:e, name, gender, item) end)
|> pick_one(name)
end

defp maybe_rule({:ok, rule}, _, _), do: {:ok, rule}

defp maybe_rule({:error, name}, gender, suffixes) do
suffixes
|> Enum.filter(fn(item) -> fits?(:r, name, gender, item) end)
|> Enum.filter(fn item -> fits?(:r, name, gender, item) end)
|> pick_one(name)
end

defp fits?(:e, name, gender, rule) do
gender?(gender, rule) and name in rule["test"]
end

defp fits?(:r, name, gender, rule) do
name_len = String.length(name)

gender?(gender, rule) and Enum.any?(rule["test"], fn(test) ->
test_len = String.length(test)
test == String.slice(name, name_len - test_len, test_len)
end)
gender?(gender, rule) and
Enum.any?(rule["test"], fn test ->
test_len = String.length(test)
test == String.slice(name, name_len - test_len, test_len)
end)
end

defp gender?(gender, rule) do
Expand All @@ -126,7 +129,7 @@ defmodule Petrovich.Parser do
items
|> Enum.at(0)
|> case do
nil -> {:error, name}
nil -> {:error, name}
rule -> {:ok, rule}
end
end
Expand Down
16 changes: 10 additions & 6 deletions lib/petrovich/stores/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,35 @@ defmodule Petrovich.Store do
@setting Keyword.get(options, :setting)

def start_link do
Agent.start_link(fn ->
load_values() end, name: unquote(caller))
Agent.start_link(
fn ->
load_values()
end,
name: unquote(caller)
)
end

def stop do
Agent.stop(unquote(caller))
end

def get(key) do
Agent.get(unquote(caller), fn(state) ->
Agent.get(unquote(caller), fn state ->
Map.get(state, key)
end)
end

def all do
Agent.get(unquote(caller), fn(state) ->
Agent.get(unquote(caller), fn state ->
state
end)
end

defp load_values do
:petrovich_elixir
|> Config.get_env(@setting)
|> File.read!
|> Poison.decode!
|> File.read!()
|> Poison.decode!()
rescue
e in File.Error ->
raise RulesFileException, message: Exception.message(e)
Expand Down
2 changes: 1 addition & 1 deletion lib/petrovich/stores/gender_store.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule Petrovich.GenderStore do
@name __MODULE__

def get(key1, key2) do
Agent.get(@name, fn(state) ->
Agent.get(@name, fn state ->
state
|> Map.get(key1)
|> Map.get(key2)
Expand Down
4 changes: 2 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
defmodule Petrovich.Mixfile do
use Mix.Project

@version "0.1.2"
@version "1.0.0"
@url "https://github.com/petrovich/petrovich_elixir"

def project do
[
app: :petrovich_elixir,
version: @version,
elixir: "~> 1.4",
elixir: "~> 1.6",
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
deps: deps(),
Expand Down
Loading

0 comments on commit 8a55771

Please sign in to comment.