Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ checkcheckcheck-*.tar
/tmp/

.elixir_ls
priv
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ To get errors and suggestions from an input file or a string:
## Examples

```
$ mix correct "hello wrld waht is up?
$ mix correct "hello wrld waht is up?"
Errors in input:
Word: wrld, Suggestions: [world, wild, weld]
Word: waht, Suggestions: [what, wat, wah]
```

```
$ ex: `mix correct ./data/inputs/ashford-short.txt`
$ mix correct ./data/inputs/ashford-short.txt
Errors in input:
Word: peaple, Suggestions: [people, peale, pepple]
Word: salteena, Suggestions: []
Expand All @@ -32,16 +32,16 @@ Simply run: `mix test`
## Performance tests

`./data/inputs/ashford-short.txt`
Total time: 1.176746s
Total time: 1.17s
Words: 490
Words per second: 416.41 word/s

`./data/inputs/ashford.txt`
Total time: 58.445784s
Total time: 58.44s
Words: 12,484
Words per second: 213.6 word/s

`"hello wrld waht is up?"`
Total time: 0.104436s
Total time: 0.10s
Words: 5
Words per second: 47.88 word/s
2 changes: 2 additions & 0 deletions data/dictionnary-sm.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
hello
world
7 changes: 4 additions & 3 deletions lib/mix/tasks/correct.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ defmodule Mix.Tasks.Correct do
end

result = SpellChecker.check(input)
# IO.inspect(result)

Enum.reduce(result, "Errors in input:\n", fn error, acc ->
acc <> "Word: #{elem(error, 1)}, Suggestions: [#{Enum.join(elem(error, 2), ", ")}]\n"
end)
# Enum.reduce(result, "Errors in input:\n", fn error, acc ->
# acc <> "Word: #{elem(error, 1)}, Suggestions: [#{Enum.join(elem(error, 2), ", ")}]\n"
# end)
end

@impl Mix.Task
Expand Down
7 changes: 7 additions & 0 deletions lib/rust_word_checker.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule RustWordChecker do
use Rustler, otp_app: :checkcheckcheck, crate: "rustwordchecker"

# When your NIF is loaded, it will override this function.
# def check(_word, _dictionnary), do: :erlang.nif_error(:nif_not_loaded)
def correct(_text, _dictionnary), do: :erlang.nif_error(:nif_not_loaded)
end
18 changes: 15 additions & 3 deletions lib/spell_checker.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule SpellChecker do
end

defp check_sentence(sentence, dictionnary) do
Enum.map(String.split(sentence), &WordChecker.check(cleaned(&1), dictionnary, 0))
Enum.map(String.split(sentence), &WordChecker.check(cleaned(&1), dictionnary))
|> Enum.filter(&match?({:error, _, _}, &1))
end

Expand All @@ -27,11 +27,23 @@ defmodule SpellChecker do
Task.await_many(tasks, 100_000) |> List.flatten()
end

RustWordChecker.correct(text, dictionnary)

{u_secs, result} = :timer.tc(run_checker)
word_count = length(String.split(text))
Logger.info("Total time: #{u_secs / 1_000_000}s")
Logger.info("Words: #{word_count}")
Logger.info("Words per second: #{(word_count / (u_secs / 1_000_000)) |> Float.ceil(2)} word/s")
# Logger.info("Words: #{word_count}")
# Logger.info("Words per second: #{(word_count / (u_secs / 1_000_000)) |> Float.ceil(2)} word/s")

# IO.inspect(result)

result

# {u_secs, result} = :timer.tc(run_checker)
# word_count = length(String.split(text))
# Logger.info("Total time: #{u_secs / 1_000_000}s")
# Logger.info("Words: #{word_count}")
# Logger.info("Words per second: #{(word_count / (u_secs / 1_000_000)) |> Float.ceil(2)} word/s")
# result
end
end
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ defmodule SpellChecker.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:rustler, "~> 0.25.0"}
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
]
Expand Down
5 changes: 5 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%{
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
"rustler": {:hex, :rustler, "0.25.0", "32526b51af7e58a740f61941bf923486ce6415a91c3934cc16c281aa201a2240", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "6b43a11a37fe79c6234d88c4102ab5dfede7a6a764dc5c7b539956cfa02f3cf4"},
"toml": {:hex, :toml, "0.6.2", "38f445df384a17e5d382befe30e3489112a48d3ba4c459e543f748c2f25dd4d1", [:mix], [], "hexpm", "d013e45126d74c0c26a38d31f5e8e9b83ea19fc752470feb9a86071ca5a672fa"},
}
5 changes: 5 additions & 0 deletions native/rustwordchecker/.cargo/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[target.'cfg(target_os = "macos")']
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
1 change: 1 addition & 0 deletions native/rustwordchecker/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
137 changes: 137 additions & 0 deletions native/rustwordchecker/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions native/rustwordchecker/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "rustwordchecker"
version = "0.1.0"
authors = []
edition = "2018"

[lib]
name = "rustwordchecker"
path = "src/lib.rs"
crate-type = ["cdylib"]

[dependencies]
rustler = "0.25.0"
20 changes: 20 additions & 0 deletions native/rustwordchecker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# NIF for Elixir.RustWordChecker

## To build the NIF module:

- Your NIF will now build along with your project.

## To load the NIF:

```elixir
defmodule RustWordChecker do
use Rustler, otp_app: :checkcheckcheck, crate: "rustwordchecker"

# When your NIF is loaded, it will override this function.
def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
end
```

## Examples

[This](https://github.com/hansihe/NifIo) is a complete example of a NIF written in Rust.
Loading