philomena/lib/search/int_parser.ex

32 lines
745 B
Elixir
Raw Normal View History

2019-11-02 19:34:25 +01:00
defmodule Search.IntParser do
import NimbleParsec
defp to_int(input), do: Search.Helpers.to_int(input)
defp range(input), do: Search.Helpers.range(input)
2019-11-02 19:34:25 +01:00
2019-11-15 19:27:10 +01:00
space =
choice([string(" "), string("\t"), string("\n"), string("\r"), string("\v"), string("\f")])
|> ignore()
2019-11-02 19:34:25 +01:00
fuzz =
string("~")
|> ignore()
int =
optional(ascii_char('-+'))
|> ascii_string([?0..?9], min: 1)
|> reduce({List, :to_string, []})
|> reduce(:to_int)
int_parser =
choice([
int |> concat(fuzz) |> integer(min: 1) |> reduce(:range) |> unwrap_and_tag(:int_range),
int |> unwrap_and_tag(:int)
])
2019-11-15 19:27:10 +01:00
|> repeat(space)
2019-11-02 19:34:25 +01:00
|> eos()
2019-11-02 21:31:55 +01:00
|> label("an integer, like `3' or `-10'")
2019-11-02 19:34:25 +01:00
defparsec :parse, int_parser
end