Packages
baby
0.25.2
0.35.1
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.1
0.30.0
0.26.0
0.25.2
0.25.1
0.25.0
0.23.0
0.22.0
0.21.1
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.4
0.16.3
0.16.1
0.16.0
0.15.1
0.15.0
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.7
0.9.6
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.0
Bushbaby Automated Bamboo Yields
Current section
Files
Jump to
Current section
Files
lib/baby/util.ex
defmodule Baby.Util do
require Logger
@moduledoc """
Utility functions for use across the codebase
"""
defp arrow(:in), do: "⇒"
defp arrow(:out), do: "⇐"
defp arrow(:both), do: "⇔"
@doc """
Standardised connection activity logging for the supplied state
`dir`: `:in`, `:out`, `:both`
`msg`: a protocol message type atom
`level`: log lvel atom (default: `:debug`)
"""
def connection_log(conn_info, dir, msg, level \\ :debug)
def connection_log(ci, d, msg, level) when is_atom(msg),
do: connection_log(ci, d, Atom.to_string(msg), level)
def connection_log(conn_info, dir, msg, level) do
Logger.log(level, Enum.join([tilde_peer(conn_info), arrow(dir), msg], " "))
end
@doc """
Logging of fatal errors takes connection info and the error
Returns `:error`
"""
def log_fatal(conn_info, error) do
Logger.log(:error, Enum.join([tilde_peer(conn_info), error], " "))
:error
end
defp tilde_peer(conn_info) do
case Map.fetch(conn_info, :short_peer) do
{:ok, them} -> them
:error -> "~unknown"
end
end
@doc """
Returns tuples of the endpoints of the widest continuous ranges
in a list of integers
iex> Baby.Util.range_points([8, 2, 5, 4, 3, 10, 11, 16, 17])
[{2, 5}, {8, 8}, {10, 11}, {16, 17}]
iex> Baby.Util.range_points([127])
[{127, 127}]
iex> Baby.Util.range_points([])
[]
"""
# Since the working part requires so many parameters and a
# distinct sorted list, we do some likely extra setup work here
# This would probably suck if the lists were too large
def range_points(list) do
list |> Enum.sort() |> Enum.uniq() |> range_points(nil, nil, [])
end
defp range_points([], nil, nil, acc), do: Enum.reverse(acc)
defp range_points([], final, first, acc),
do: range_points([], nil, nil, [{first, final} | acc])
defp range_points([n | rest], curr, first, acc) do
cond do
curr == nil -> range_points(rest, n, n, acc)
curr == n - 1 -> range_points(rest, n, first, acc)
true -> range_points(rest, n, n, [{first, curr} | acc])
end
end
@doc """
Convert a `{count, unit}` period into a number of milliseconds
## Examples
iex> Baby.Util.period_to_ms({1, :hour})
3_600_000
iex> Baby.Util.period_to_ms({17, :minute})
1_020_000
"""
@spec period_to_ms({integer, atom}) :: integer | :error
def period_to_ms(period)
def period_to_ms({amt, :millisecond}), do: amt
def period_to_ms({amt, :second}), do: period_to_ms({amt * 1000, :millisecond})
def period_to_ms({amt, :minute}), do: period_to_ms({amt * 60, :second})
def period_to_ms({amt, :hour}), do: period_to_ms({amt * 60, :minute})
def period_to_ms({amt, :day}), do: period_to_ms({amt * 24, :hour})
def period_to_ms({amt, :week}), do: period_to_ms({amt * 7, :day})
def period_to_ms(_), do: :error
@doc """
A simple wrapper to convert a host binary into an IP tuple
"""
def host_to_ip(host) when is_binary(host) do
where = to_charlist(host)
case :inet.gethostbyname(where) do
{:ok, {:hostent, _, _, _, _, [addr | _more]}} ->
addr
_ ->
case :inet.parse_ipv6_address(where) do
{:ok, addr} -> addr
_ -> :error
end
end
end
def host_to_ip(_), do: :error
end