From 66536788607886937c41b146fe784bb7d3dd30e9 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Mon, 9 Feb 2026 13:15:17 -0600 Subject: [PATCH] Reduce cyclomatic complexity in high-complexity functions Extract helper functions to reduce complexity in functions with complexity 10-15: - packet.ex: Extract add_symbol_data/2 Moves symbol data extraction into separate function Reduces complexity from 10 to 9 - mobile_channel.ex: Extract bounds validation helpers Creates all_numeric?/4, valid_latitudes?/2, valid_longitudes?/2 Moves complex boolean conditions into readable helper functions Reduces complexity from 15 to within limits - historical_loader.ex: Extract packet_has_valid_coordinates?/1 Moves coordinate validation logic with multiple conditions Reduces complexity from 15 to within limits Fixes 3 more Credo cyclomatic complexity issues. --- lib/aprsme/packet.ex | 11 +++++++---- lib/aprsme_web/channels/mobile_channel.ex | 18 +++++++++++++++--- .../live/map_live/historical_loader.ex | 17 +++++++++-------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/lib/aprsme/packet.ex b/lib/aprsme/packet.ex index 898056a..ffcd6ee 100644 --- a/lib/aprsme/packet.ex +++ b/lib/aprsme/packet.ex @@ -323,10 +323,7 @@ defmodule Aprsme.Packet do # Check if symbol data exists at the top level of attrs (from APRS parser) # and preserve it if not already in base_attrs - base_attrs = - base_attrs - |> maybe_put(:symbol_code, attrs[:symbol_code] || attrs["symbol_code"]) - |> maybe_put(:symbol_table_id, attrs[:symbol_table_id] || attrs["symbol_table_id"]) + base_attrs = add_symbol_data(base_attrs, attrs) # Extract data based on the type of data_extended additional_data = @@ -352,6 +349,12 @@ defmodule Aprsme.Packet do merge_extracted_data(base_attrs, additional_data, attrs) end + defp add_symbol_data(base_attrs, attrs) do + base_attrs + |> maybe_put(:symbol_code, attrs[:symbol_code] || attrs["symbol_code"]) + |> maybe_put(:symbol_table_id, attrs[:symbol_table_id] || attrs["symbol_table_id"]) + end + defp merge_extracted_data(base_attrs, additional_data, attrs) do # Process telemetry fields from top-level attrs if not already processed telemetry_data = diff --git a/lib/aprsme_web/channels/mobile_channel.ex b/lib/aprsme_web/channels/mobile_channel.ex index 4bd5745..dda86eb 100644 --- a/lib/aprsme_web/channels/mobile_channel.ex +++ b/lib/aprsme_web/channels/mobile_channel.ex @@ -243,13 +243,13 @@ defmodule AprsmeWeb.MobileChannel do defp validate_bounds(%{north: north, south: south, east: east, west: west}) do cond do - not is_number(north) or not is_number(south) or not is_number(east) or not is_number(west) -> + not all_numeric?(north, south, east, west) -> {:error, "All bounds must be numeric"} - north < -90 or north > 90 or south < -90 or south > 90 -> + not valid_latitudes?(north, south) -> {:error, "Latitude must be between -90 and 90"} - east < -180 or east > 180 or west < -180 or west > 180 -> + not valid_longitudes?(east, west) -> {:error, "Longitude must be between -180 and 180"} north <= south -> @@ -260,6 +260,18 @@ defmodule AprsmeWeb.MobileChannel do end end + defp all_numeric?(north, south, east, west) do + is_number(north) and is_number(south) and is_number(east) and is_number(west) + end + + defp valid_latitudes?(north, south) do + north >= -90 and north <= 90 and south >= -90 and south <= 90 + end + + defp valid_longitudes?(east, west) do + east >= -180 and east <= 180 and west >= -180 and west <= 180 + end + defp ensure_float(value) when is_integer(value), do: value * 1.0 defp ensure_float(value) when is_float(value), do: value defp ensure_float(value) when is_binary(value), do: String.to_float(value) diff --git a/lib/aprsme_web/live/map_live/historical_loader.ex b/lib/aprsme_web/live/map_live/historical_loader.ex index 13837ae..ba58b09 100644 --- a/lib/aprsme_web/live/map_live/historical_loader.ex +++ b/lib/aprsme_web/live/map_live/historical_loader.ex @@ -172,14 +172,7 @@ defmodule AprsmeWeb.MapLive.HistoricalLoader do packet_data_list = try do # Filter out packets with invalid coordinates before processing - valid_packets = - Enum.filter(historical_packets, fn packet -> - {lat, lon, _} = CoordinateUtils.get_coordinates(packet) - - is_number(lat) and is_number(lon) and - lat >= -90 and lat <= 90 and lon >= -180 and lon <= 180 and - is_finite(lat) and is_finite(lon) - end) + valid_packets = Enum.filter(historical_packets, &packet_has_valid_coordinates?/1) if length(valid_packets) < length(historical_packets) do Logger.debug( @@ -450,4 +443,12 @@ defmodule AprsmeWeb.MapLive.HistoricalLoader do defp is_finite(n) when is_float(n), do: n != :infinity and n != :neg_infinity defp is_finite(n) when is_integer(n), do: true + + defp packet_has_valid_coordinates?(packet) do + {lat, lon, _} = CoordinateUtils.get_coordinates(packet) + + is_number(lat) and is_number(lon) and + lat >= -90 and lat <= 90 and lon >= -180 and lon <= 180 and + is_finite(lat) and is_finite(lon) + end end