Skip to content

Commit 6a5b710

Browse files
authored
Improve docs and cleanup Radius.Dict module (#8)
1 parent fdb3329 commit 6a5b710

6 files changed

Lines changed: 142 additions & 35 deletions

File tree

lib/radius/dict.ex

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
defmodule Radius.Dict do
2-
alias Radius.Dict.Parser
2+
@moduledoc """
3+
Parses dictionaries and generates lookup functions and helper macro's.
4+
5+
The helper macro's give the benefit of compile time checks and faster encoding without losing
6+
readability.
7+
"""
8+
require Radius.Dict.Helpers
39
alias Radius.Dict.EntryNotFoundError
10+
alias Radius.Dict.Helpers
11+
alias Radius.Dict.Parser
412

513
defmacro __using__(_) do
614
quote do
@@ -59,39 +67,41 @@ defmodule Radius.Dict do
5967
end
6068
)
6169

62-
for attribute <- attributes do
63-
attr_fun_name = "attr_#{attribute.name}" |> String.replace("-", "_") |> String.to_atom()
70+
Helpers.define_attribute_doc_helpers()
6471

65-
defmacro unquote(attr_fun_name)(), do: unquote(attribute.id)
66-
defmacro unquote(attr_fun_name)(val), do: {unquote(attribute.id), val}
67-
def attribute_by_id(unquote(attribute.id)), do: unquote(Macro.escape(attribute))
68-
def attribute_by_name(unquote(attribute.name)), do: unquote(Macro.escape(attribute))
72+
for attribute <- attributes do
73+
Helpers.define_attribute_functions(attribute)
6974
end
7075

71-
for val <- values do
72-
val_fun_name = "val_#{val.attr}_#{val.name}" |> String.replace("-", "_") |> String.to_atom()
76+
Helpers.define_value_doc_helpers()
7377

74-
defmacro unquote(val_fun_name)(), do: unquote(val.value)
75-
def value_by_value(unquote(val.attr), unquote(val.value)), do: unquote(Macro.escape(val))
76-
def value_by_name(unquote(val.attr), unquote(val.name)), do: unquote(Macro.escape(val))
78+
for val <- values do
79+
Helpers.define_value_functions(val)
7780
end
7881

82+
@doc """
83+
Get vendor struct based on vendor id
84+
"""
85+
@doc group: :lookup
86+
def vendor_by_id(attr_id)
87+
88+
@doc """
89+
Get vendor struct based on vendor name
90+
"""
91+
@doc group: :lookup
92+
def vendor_by_name(attr_name)
93+
7994
for vendor <- vendors do
80-
mod = Module.concat(__MODULE__, :"Vendor#{String.replace(vendor.name, "-", "_")}")
95+
mod = Module.concat(__MODULE__, Helpers.safe_name("Vendor#{vendor.name}"))
8196
[tl, ll] = Keyword.get(vendor.opts, :format) || [1, 1]
8297
vendor_data = %{id: vendor.id, name: vendor.name, format: {tl, ll}, module: mod}
8398
def vendor_by_id(unquote(vendor.id)), do: unquote(Macro.escape(vendor_data))
8499
def vendor_by_name(unquote(vendor.name)), do: unquote(Macro.escape(vendor_data))
85100

86101
attribute_funs =
87102
for attribute <- vendor.attributes do
88-
attr_fun_name = "attr_#{attribute.name}" |> String.replace("-", "_") |> String.to_atom()
89-
90-
quote location: :keep do
91-
defmacro unquote(attr_fun_name)(), do: unquote(attribute.id)
92-
defmacro unquote(attr_fun_name)(val), do: {unquote(attribute.id), val}
93-
def attribute_by_id(unquote(attribute.id)), do: unquote(Macro.escape(attribute))
94-
def attribute_by_name(unquote(attribute.name)), do: unquote(Macro.escape(attribute))
103+
quote do
104+
unquote(Helpers.generate_attribute_functions(Macro.escape(attribute)))
95105
end
96106
end
97107

@@ -100,22 +110,13 @@ defmodule Radius.Dict do
100110
value_funs =
101111
if Enum.count(vendor.attributes ++ vendor.values) < elixir_compiler_limit do
102112
for val <- vendor.values do
103-
val_fun_name =
104-
"val_#{val.attr}_#{val.name}" |> String.replace("-", "_") |> String.to_atom()
105-
106-
quote location: :keep do
107-
defmacro unquote(val_fun_name)(), do: unquote(val.value)
108-
109-
def value_by_value(unquote(val.attr), unquote(val.value)),
110-
do: unquote(Macro.escape(val))
111-
112-
def value_by_name(unquote(val.attr), unquote(val.name)),
113-
do: unquote(Macro.escape(val))
113+
quote do
114+
unquote(Helpers.generate_value_functions(Macro.escape(val)))
114115
end
115116
end
116117
else
117118
for {attr, vals} <- Enum.group_by(vendor.values, & &1.attr) do
118-
val_fun_name = "val_#{attr}" |> String.replace("-", "_") |> String.to_atom()
119+
val_fun_name = Helpers.safe_name("val_#{attr}")
119120

120121
quote location: :keep do
121122
defmacro unquote(val_fun_name)(val_name),
@@ -143,7 +144,14 @@ defmodule Radius.Dict do
143144
end
144145

145146
IO.puts("Compiling #{mod}")
146-
Module.create(mod, attribute_funs ++ value_funs, Macro.Env.location(__ENV__))
147+
148+
value_doc_funs = if value_funs == [], do: [], else: [Helpers.generate_value_doc_helpers()]
149+
150+
module_body =
151+
[Helpers.generate_attribute_doc_helpers()] ++
152+
attribute_funs ++ value_funs ++ value_doc_funs
153+
154+
Module.create(mod, module_body, Macro.Env.location(__ENV__))
147155
end
148156

149157
def attribute_by_id(id), do: raise(EntryNotFoundError, type: :attribute, key: id)

lib/radius/dict/helpers.ex

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
defmodule Radius.Dict.Helpers do
2+
@moduledoc false
3+
defmacro define_attribute_doc_helpers() do
4+
generate_attribute_doc_helpers()
5+
end
6+
7+
defmacro define_attribute_functions(attribute) do
8+
generate_attribute_functions(attribute)
9+
end
10+
11+
defmacro define_value_doc_helpers() do
12+
generate_value_doc_helpers()
13+
end
14+
15+
defmacro define_value_functions(val) do
16+
generate_value_functions(val)
17+
end
18+
19+
def generate_attribute_doc_helpers() do
20+
quote do
21+
@doc """
22+
Get attribute struct based on attribute id
23+
"""
24+
@doc group: :lookup
25+
def attribute_by_id(attr_id)
26+
27+
@doc """
28+
Get attribute struct based on attribute name
29+
"""
30+
@doc group: :lookup
31+
def attribute_by_name(attr_name)
32+
end
33+
end
34+
35+
def generate_attribute_functions(attribute) do
36+
quote bind_quoted: [attribute: attribute] do
37+
attr_fun_name = "attr_#{attribute.name}" |> String.replace("-", "_") |> String.to_atom()
38+
39+
@doc group: :attributes
40+
defmacro unquote(attr_fun_name)(), do: unquote(attribute.id)
41+
@doc group: :attributes
42+
defmacro unquote(attr_fun_name)(val), do: {unquote(attribute.id), val}
43+
def attribute_by_id(unquote(attribute.id)), do: unquote(Macro.escape(attribute))
44+
def attribute_by_name(unquote(attribute.name)), do: unquote(Macro.escape(attribute))
45+
end
46+
end
47+
48+
def generate_value_doc_helpers() do
49+
quote do
50+
@doc """
51+
Get value struct based on attribute name and value name
52+
"""
53+
@doc group: :lookup
54+
def value_by_name(attr_name, value_name)
55+
56+
@doc """
57+
Get value struct based on attribute name and the value
58+
"""
59+
@doc group: :lookup
60+
def value_by_value(attr_name, value)
61+
end
62+
end
63+
64+
def generate_value_functions(val) do
65+
quote bind_quoted: [val: val] do
66+
val_fun_name = "val_#{val.attr}_#{val.name}" |> String.replace("-", "_") |> String.to_atom()
67+
68+
@doc group: :values
69+
defmacro unquote(val_fun_name)(), do: unquote(val.value)
70+
def value_by_value(unquote(val.attr), unquote(val.value)), do: unquote(Macro.escape(val))
71+
def value_by_name(unquote(val.attr), unquote(val.name)), do: unquote(Macro.escape(val))
72+
end
73+
end
74+
75+
def safe_name(name) do
76+
name |> String.replace("-", "_") |> String.to_atom()
77+
end
78+
end

lib/radius/dict/parser.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Default for opts on `parse_bin/2` manually removed to get rid of warning
22
# Generated from lib/radius/dict/parser.ex.exs, do not edit.
3-
# Generated at 2023-06-06 13:43:01Z.
3+
# Generated at 2023-06-12 12:12:16Z.
44

55
defmodule Radius.Dict.Parser do
6+
@moduledoc false
67
def parse(binary) do
78
{:ok, _, "", ctx, _, _} =
89
parse_bin(binary, context: [attributes: [], values: [], prepend_key: []])

lib/radius/dict/parser.ex.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Radius.Dict.Parser do
2+
@moduledoc false
23
def parse(binary) do
34
{:ok, _, "", ctx, _, _} =
45
parse_bin(binary, context: [attributes: [], values: [], prepend_key: []])

lib/radius/util.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Radius.Util do
2+
@moduledoc false
23
require Logger
34
import Bitwise
45

mix.exs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ defmodule RadiusProxy.Mixfile do
66
app: :elixir_radius,
77
version: "2.0.0",
88
elixir: "~> 1.12",
9+
deps: deps(),
10+
name: "Radius",
911
description: desc(),
1012
package: package(),
11-
deps: deps()
13+
source_url: "https://github.com/bearice/elixir-radius",
14+
docs: docs()
1215
]
1316
end
1417

@@ -52,4 +55,19 @@ defmodule RadiusProxy.Mixfile do
5255
links: %{"Github" => "https://github.com/bearice/elixir-radius"}
5356
]
5457
end
58+
59+
defp docs() do
60+
[
61+
main: "README",
62+
extras: ["README.md"],
63+
groups_for_modules: [
64+
"Vendor Dictionaries": ~r/Radius\.Dict\.Vendor.+/
65+
],
66+
groups_for_docs: [
67+
"Lookup Functions": &(&1[:group] == :lookup),
68+
Attributes: &(&1[:group] == :attributes),
69+
Values: &(&1[:group] == :values)
70+
]
71+
]
72+
end
5573
end

0 commit comments

Comments
 (0)