1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
defmodule Irc.Parser.Isupport do
@moduledoc """
ISUPPORT list parser.
"""
@typedoc "Server ISUPPORT."
@type t :: %{key => value}
@type key :: String.t
@type value :: true | Integer.t() | Map.t() | prefix_map
@type prefix :: String.t()
@type mode :: String.t()
@type prefix_map :: %{prefix() => mode()}
def parse(list, acc \\ %{}) do
list = List.flatten(list)
Enum.reduce(list, acc, fn(entry, acc) ->
case String.split(entry, "=", parts: 2) do
[entry] ->
if String.contains?(entry, " ") do
acc
else
Map.put(acc, entry, true)
end
[entry, value] -> Map.put(acc, entry, parse_value(entry, value))
end
end)
end
defp parse_value(entry, value) do
if String.contains?(value, ":") do
Enum.reduce(String.split(value, ","), %{}, fn(key_and_value, acc) ->
case String.split(key_and_value, ":", parts: 2) do
[key] -> Map.put(acc, key, nil)
[key, value] -> Map.put(acc, key, format_value(key, value))
end
end)
else
format_value(entry, value)
end
end
def format_value("PREFIX", value) do
case String.split(value, ")", parts: 2) do
["("<>modes, prefixes] ->
modes = String.split(modes, "", trim: true)
prefixes = String.split(prefixes, "", trim: true)
Enum.reduce(Enum.with_index(modes), %{}, fn({mode, position}, acc) ->
Map.put(acc, Enum.at(prefixes, position), mode)
end)
end
end
def format_value(key, value) do
case Integer.parse(value) do
{i, ""} -> i
_ -> value
end
end
end
|