Skip to content

Commit

Permalink
feat: unify enum __str__ by adding ReprEnum
Browse files Browse the repository at this point in the history
  • Loading branch information
M0r13n committed Nov 1, 2024
1 parent 6ce6a88 commit 53bd16b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 13 deletions.
32 changes: 19 additions & 13 deletions pyais/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import typing
from enum import Enum, IntEnum
from enum import Enum

# Keywords
UNDEFINED = 'Undefined'
Expand All @@ -9,7 +9,13 @@
ANSI_RESET = '\x1b[0m'


class TurnRate(float, Enum):
class ReprEnum(Enum):

def __str__(self) -> str:
return str(self.value)


class TurnRate(float, ReprEnum):
# Source: https://gpsd.gitlab.io/gpsd/AIVDM.html#_types_1_2_and_3_position_report_class_a
# turning right at more than 5deg/30s (No TI available)
NO_TI_RIGHT = 127
Expand All @@ -19,7 +25,7 @@ class TurnRate(float, Enum):
NO_TI_DEFAULT = -128


class TalkerID(str, Enum):
class TalkerID(str, ReprEnum):
""" Enum of all NMEA talker IDs.
See: https://gpsd.gitlab.io/gpsd/AIVDM.html#_talker_ids"""
Base_Station = "AB"
Expand All @@ -43,7 +49,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["TalkerID
return cls(v) if v is not None else None


class NavigationStatus(IntEnum):
class NavigationStatus(int, ReprEnum):
UnderWayUsingEngine = 0
AtAnchor = 1
NotUnderCommand = 2
Expand All @@ -70,7 +76,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["Navigati
return cls(v) if v is not None else None


class ManeuverIndicator(IntEnum):
class ManeuverIndicator(int, ReprEnum):
NotAvailable = 0
NoSpecialManeuver = 1
SpecialManeuver = 2
Expand All @@ -85,7 +91,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["Maneuver
return cls(v) if v is not None else None


class EpfdType(IntEnum):
class EpfdType(int, ReprEnum):
Undefined = 0
GPS = 1
GLONASS = 2
Expand All @@ -106,7 +112,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["EpfdType
return cls(v) if v is not None else None


class ShipType(IntEnum):
class ShipType(int, ReprEnum):
NotAvailable = 0
# 20's
WIG = 20
Expand Down Expand Up @@ -207,7 +213,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["ShipType
return cls(v) if v is not None else None


class DacFid(IntEnum):
class DacFid(int, ReprEnum):
DangerousCargoIndication = 13
TidalWindow = 15
NumPersonsOnBoard = 17
Expand All @@ -226,7 +232,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["DacFid"]
return cls(v) if v is not None else None


class NavAid(IntEnum):
class NavAid(int, ReprEnum):
DEFAULT = 0
REFERENCE_POINT = 1
RACON = 2
Expand Down Expand Up @@ -269,7 +275,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["NavAid"]
return cls(v) if v is not None else None


class TransmitMode(IntEnum):
class TransmitMode(int, ReprEnum):
TXA_TXB_RXA_RXB = 0 # default
TXA_RXA_RXB = 1
TXB_RXA_RXB = 2
Expand All @@ -284,7 +290,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["Transmit
return cls(v) if v is not None else None


class StationType(IntEnum):
class StationType(int, ReprEnum):
ALL = 0
RESERVED = 1
CLASS_B_ALL = 2
Expand All @@ -307,7 +313,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["StationT
return cls(v) if v is not None else None


class StationIntervals(IntEnum):
class StationIntervals(int, ReprEnum):
AUTONOMOUS_MODE = 0
MINUTES_10 = 1
MINUTES_6 = 2
Expand All @@ -330,7 +336,7 @@ def from_value(cls, v: typing.Optional[typing.Any]) -> typing.Optional["StationI
return cls(v) if v is not None else None


class SyncState(IntEnum):
class SyncState(int, ReprEnum):
"""
https://www.navcen.uscg.gov/?pageName=AISMessagesA#Sync
"""
Expand Down
33 changes: 33 additions & 0 deletions tests/test_repr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import unittest
from pyais.constants import TurnRate, TalkerID, NavigationStatus, ManeuverIndicator, EpfdType, ShipType


class TestPyAISConstants(unittest.TestCase):

def test_turn_rate_no_ti_default(self):
self.assertEqual(repr(TurnRate.NO_TI_DEFAULT), "<TurnRate.NO_TI_DEFAULT: -128.0>")
self.assertEqual(str(TurnRate.NO_TI_DEFAULT), "-128.0")

def test_talker_id_base_station(self):
self.assertEqual(repr(TalkerID.Base_Station), "<TalkerID.Base_Station: 'AB'>")
self.assertEqual(str(TalkerID.Base_Station), "AB")

def test_navigation_status_aground(self):
self.assertEqual(repr(NavigationStatus.Aground), "<NavigationStatus.Aground: 6>")
self.assertEqual(str(NavigationStatus.Aground), "6")

def test_maneuver_indicator_no_special_maneuver(self):
self.assertEqual(repr(ManeuverIndicator.NoSpecialManeuver), "<ManeuverIndicator.NoSpecialManeuver: 1>")
self.assertEqual(str(ManeuverIndicator.NoSpecialManeuver), "1")

def test_epfd_type_glonass(self):
self.assertEqual(repr(EpfdType.GLONASS), "<EpfdType.GLONASS: 2>")
self.assertEqual(str(EpfdType.GLONASS), "2")

def test_ship_type_wig_hazardous_category_a(self):
self.assertEqual(repr(ShipType.WIG_HazardousCategory_A), "<ShipType.WIG_HazardousCategory_A: 21>")
self.assertEqual(str(ShipType.WIG_HazardousCategory_A), "21")


if __name__ == '__main__':
unittest.main()

0 comments on commit 53bd16b

Please sign in to comment.