Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 2s
45 lines
1.5 KiB
Elixir
45 lines
1.5 KiB
Elixir
defmodule Aprsme.Callsign do
|
|
@moduledoc """
|
|
Validation and normalization for APRS source identifiers.
|
|
|
|
RF callsigns follow AX.25's shorter shape, while APRS-IS also carries
|
|
application and gateway identifiers. Validation therefore enforces a
|
|
conservative transport-safe character set and length without rejecting
|
|
established APRS-IS identifiers.
|
|
"""
|
|
|
|
@safe_identifier_regex ~r/^[A-Z0-9]+(?:-[A-Z0-9]+)*$/
|
|
|
|
@spec valid?(term()) :: boolean()
|
|
def valid?(callsign) when is_binary(callsign) do
|
|
normalized = normalize(callsign)
|
|
byte_size(normalized) in 1..20 and Regex.match?(@safe_identifier_regex, normalized)
|
|
end
|
|
|
|
def valid?(_callsign), do: false
|
|
|
|
@spec normalize(term()) :: String.t()
|
|
def normalize(callsign) when is_binary(callsign), do: callsign |> String.trim() |> String.upcase()
|
|
def normalize(_callsign), do: ""
|
|
|
|
@spec matches?(term(), term()) :: boolean()
|
|
def matches?(left, right), do: normalize(left) == normalize(right)
|
|
|
|
@spec extract_base(term()) :: String.t()
|
|
def extract_base(callsign), do: callsign |> extract_parts() |> elem(0)
|
|
|
|
@spec extract_ssid(term()) :: String.t()
|
|
def extract_ssid(callsign), do: callsign |> extract_parts() |> elem(1)
|
|
|
|
@spec extract_parts(term()) :: {String.t(), String.t()}
|
|
def extract_parts(callsign) when is_binary(callsign) do
|
|
normalized = normalize(callsign)
|
|
|
|
case Regex.run(~r/^(.*)-([0-9]+)$/, normalized) do
|
|
[_, base, ssid] -> {base, ssid}
|
|
_ -> {normalized, "0"}
|
|
end
|
|
end
|
|
|
|
def extract_parts(_callsign), do: {"", "0"}
|
|
end
|