Skip to content

Commit 4d8c004

Browse files
committed
Enable credo spec check
And add all the needed specs for credo to pass
1 parent 61d99c8 commit 4d8c004

19 files changed

+136
-27
lines changed

.credo.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
checks: [
77
{Credo.Check.Readability.LargeNumbers, only_greater_than: 86400},
88
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, parens: true},
9-
# {Credo.Check.Readability.Specs, tags: []},
9+
{Credo.Check.Readability.Specs, tags: []},
1010

1111
# Report TODO comments, but don't fail the check
1212
{Credo.Check.Design.TagTODO, exit_status: 0}

lib/jeff/bus.ex

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,47 @@ defmodule Jeff.Bus do
1111
conn: nil,
1212
controlling_process: nil
1313

14+
@type t :: %__MODULE__{}
15+
16+
@spec new(keyword()) :: t()
1417
def new(_opts \\ []) do
1518
%__MODULE__{}
1619
end
1720

21+
@spec add_device(t(), keyword()) :: t()
1822
def add_device(bus, opts \\ []) do
1923
device = Device.new(opts)
2024
_bus = register(bus, device.address, device)
2125
end
2226

27+
@spec remove_device(t(), byte()) :: t()
2328
def remove_device(%{poll: poll, registry: registry} = bus, address) do
2429
registry = Map.delete(registry, address)
2530
poll = Enum.reject(poll, &(&1 == address))
2631
%{bus | poll: poll, registry: registry}
2732
end
2833

34+
@spec get_device(t(), byte()) :: Device.t()
2935
def get_device(%{registry: registry}, address) do
3036
Map.fetch!(registry, address)
3137
end
3238

39+
@spec registered?(t(), byte()) :: boolean()
3340
def registered?(%{registry: registry}, address) do
3441
is_map_key(registry, address)
3542
end
3643

44+
@spec put_device(t(), Device.t()) :: t()
3745
def put_device(%{cursor: cursor} = bus, device) do
3846
register(bus, cursor, device)
3947
end
4048

49+
@spec put_device(t(), byte(), Device.t()) :: t()
4150
def put_device(bus, address, device) do
4251
register(bus, address, device)
4352
end
4453

54+
@spec current_device(%__MODULE__{cursor: byte(), registry: map()}) :: Device.t()
4555
def current_device(%{cursor: cursor} = bus) do
4656
get_device(bus, cursor)
4757
end
@@ -55,6 +65,7 @@ defmodule Jeff.Bus do
5565
_bus = register(bus, cursor, device)
5666
end
5767

68+
@spec tick(t()) :: t()
5869
def tick(%{cursor: nil, poll: []} = bus) do
5970
poll = addresses(bus)
6071
%{bus | poll: poll}
@@ -93,11 +104,13 @@ defmodule Jeff.Bus do
93104
register(bus, device)
94105
end
95106

107+
@spec send_command(t(), Jeff.Command.t()) :: t()
96108
def send_command(bus, %{address: address} = command) do
97109
device = get_device(bus, address) |> Device.send_command(command)
98-
_bus = register(bus, address, device)
110+
register(bus, address, device)
99111
end
100112

113+
@spec receive_reply(t(), Jeff.Reply.t()) :: t()
101114
def receive_reply(bus, reply) do
102115
%{bus | reply: reply}
103116
end

lib/jeff/command.ex

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ defmodule Jeff.Command do
3636
address: byte(),
3737
code: byte(),
3838
data: binary(),
39-
name: atom(),
39+
name: name(),
4040
caller: reference()
4141
}
4242

@@ -83,6 +83,10 @@ defmodule Jeff.Command do
8383
}
8484
@codes Map.new(@names, fn {code, name} -> {name, code} end)
8585

86+
@type name :: unquote(Enum.reduce(Map.values(@names), &{:|, [], [&1, &2]}))
87+
@type code :: unquote(Enum.reduce(Map.keys(@names), &{:|, [], [&1, &2]}))
88+
89+
@spec new(Jeff.osdp_address(), name(), keyword()) :: t()
8690
def new(address, name, params \\ []) do
8791
{caller, params} = Keyword.pop(params, :caller)
8892

@@ -116,6 +120,8 @@ defmodule Jeff.Command do
116120
defp encode(ACURXSIZE, size: size), do: <<size::size(16)-little>>
117121
defp encode(ABORT, _params), do: nil
118122

123+
@spec code(name()) :: code()
119124
def code(name), do: @codes[name]
125+
@spec name(code()) :: name()
120126
def name(code), do: @names[code]
121127
end

lib/jeff/command/challenge_data.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule Jeff.Command.ChallengeData do
22
@moduledoc false
33

4+
@spec encode(server_rnd: binary()) :: binary()
45
def encode(server_rnd: rnd), do: rnd
56
end

lib/jeff/command/encryption_key.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ defmodule Jeff.Command.EncryptionKey do
55

66
defstruct [:key, type: @secure_channel_base_key]
77

8+
@type t :: %__MODULE__{key: binary(), type: 0x01}
9+
10+
@spec new(key: binary()) :: t()
811
def new(key: key) do
912
%__MODULE__{key: key}
1013
end
1114

15+
@spec encode(key: binary()) :: <<_::24>>
1216
def encode(params) do
1317
%{key: key, type: type} = new(params)
1418
<<type, key_length(key)>> <> key
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Jeff.Command.EncryptionServer do
22
@moduledoc false
3+
@spec encode(cryptogram: binary()) :: binary()
34
def encode(cryptogram: cryptogram), do: cryptogram
45
end

lib/jeff/command/output_settings.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ defmodule Jeff.Command.OutputSettings do
1717
| 0x06 | Set the temporary state to OFF, resume permanent state on timeout |
1818
"""
1919

20+
@spec encode(output: pos_integer(), code: pos_integer(), timer: pos_integer()) :: <<_::32>>
2021
def encode(output: output, code: code, timer: timer) do
2122
<<output, code, timer::size(2)-unit(8)-little>>
2223
end

lib/jeff/command/text_settings.ex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ defmodule Jeff.Command.TextSettings do
1010
length: 0x00,
1111
content: ""
1212

13+
@spec new(keyword()) :: %__MODULE__{}
1314
def new(params \\ []) do
1415
settings = struct(__MODULE__, params)
1516
%{settings | length: byte_size(settings.content)}
1617
end
1718

19+
@spec encode(keyword()) :: <<_::48>>
1820
def encode(params) do
1921
settings = new(params)
2022

lib/jeff/control_info.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
defmodule Jeff.ControlInfo do
22
@moduledoc false
33

4+
@spec encode(Jeff.Message.t()) :: byte()
45
def encode(%{sequence: seq, check_scheme: cs, security?: sec}) do
56
encode(seq, cs, sec)
67
end
78

9+
@spec encode(byte(), Jeff.Device.check_scheme(), boolean()) :: byte()
810
def encode(sequence, check_scheme, security?) do
911
check_scheme =
1012
case check_scheme do
@@ -28,6 +30,7 @@ defmodule Jeff.ControlInfo do
2830
byte
2931
end
3032

33+
@spec decode(byte() | integer()) :: {integer(), Jeff.Device.check_scheme(), boolean()}
3134
def decode(<<byte>>), do: decode(byte)
3235

3336
def decode(byte) when is_integer(byte) do

lib/jeff/device.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ defmodule Jeff.Device do
2828

2929
@offline_threshold_ms 8000
3030

31+
@spec new(keyword()) :: t()
3132
def new(params \\ []) do
3233
secure_channel = SecureChannel.new()
3334

@@ -36,6 +37,7 @@ defmodule Jeff.Device do
3637
|> Map.put(:secure_channel, secure_channel)
3738
end
3839

40+
@spec inc_sequence(t()) :: t()
3941
def inc_sequence(%{sequence: n} = device) do
4042
%{device | sequence: next_sequence(n)}
4143
end
@@ -53,17 +55,20 @@ defmodule Jeff.Device do
5355

5456
defp next_sequence(n), do: rem(n, 3) + 1
5557

58+
@spec online?(t()) :: boolean()
5659
def online?(%{last_valid_reply: nil}), do: false
5760

5861
def online?(%{last_valid_reply: last_valid_reply}) do
5962
last_valid_reply - System.monotonic_time(:millisecond) < @offline_threshold_ms
6063
end
6164

65+
@spec send_command(t(), Command.t()) :: t()
6266
def send_command(%{commands: commands} = device, command) do
6367
commands = :queue.in(command, commands)
6468
%{device | commands: commands}
6569
end
6670

71+
@spec next_command(t()) :: {t(), Command.t()}
6772
def next_command(%{sequence: 0, address: address} = device) do
6873
command = Command.new(address, POLL)
6974
{device, command}

0 commit comments

Comments
 (0)