Coverage for zenmqtt/mqtt/codec.py: 100%

14 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-12 21:55 +0000

1from typing import Callable, Final, Mapping, Union 

2 

3from zenmqtt.exceptions import MalformedPacketError, ProtocolError 

4from zenmqtt.mqtt.auth import AuthResult, parse_auth_packet 

5from zenmqtt.mqtt.connect import ( 

6 ConnectionResult, 

7 ServerDisconnect, 

8 parse_connack_packet, 

9 parse_disconnect_packet, 

10) 

11from zenmqtt.mqtt.packet import BytesReader, FixedHeader, PacketType 

12from zenmqtt.mqtt.ping import PingRespResult, parse_pingresp_packet 

13from zenmqtt.mqtt.publish import ( 

14 MQTTMessage, 

15 PubAckResult, 

16 PubCompResult, 

17 PubRecResult, 

18 PubRelResult, 

19 parse_puback_packet, 

20 parse_pubcomp_packet, 

21 parse_publish_packet, 

22 parse_pubrec_packet, 

23 parse_pubrel_packet, 

24) 

25from zenmqtt.mqtt.subscribe import ( 

26 SubscribeResult, 

27 UnsubscribeResult, 

28 parse_suback_packet, 

29 parse_unsuback_packet, 

30) 

31 

32# packets a client receives from the server 

33IncomingPacket = Union[ 

34 MQTTMessage, 

35 PubAckResult, 

36 PubRecResult, 

37 PubRelResult, 

38 PubCompResult, 

39 SubscribeResult, 

40 UnsubscribeResult, 

41 PingRespResult, 

42 ConnectionResult, 

43 ServerDisconnect, 

44 AuthResult, 

45] 

46 

47PARSERS: Final[ 

48 Mapping[PacketType, Callable[[FixedHeader, BytesReader], IncomingPacket]] 

49] = { 

50 PacketType.CONNACK: parse_connack_packet, 

51 PacketType.PUBLISH: parse_publish_packet, 

52 PacketType.PUBACK: parse_puback_packet, 

53 PacketType.PUBREC: parse_pubrec_packet, 

54 PacketType.PUBREL: parse_pubrel_packet, 

55 PacketType.PUBCOMP: parse_pubcomp_packet, 

56 PacketType.SUBACK: parse_suback_packet, 

57 PacketType.UNSUBACK: parse_unsuback_packet, 

58 PacketType.PINGRESP: parse_pingresp_packet, 

59 PacketType.DISCONNECT: parse_disconnect_packet, 

60 PacketType.AUTH: parse_auth_packet, 

61} 

62 

63 

64def decode(header: FixedHeader, reader: BytesReader) -> IncomingPacket: 

65 if (parser := PARSERS.get(header.packet_type)) is None: 

66 # type 0 is reserved, the others are sent only by clients 

67 raise ( 

68 MalformedPacketError 

69 if header.packet_type == PacketType.RESERVED 

70 else ProtocolError 

71 )(f"Unexpected packet type: {header.packet_type.name}") 

72 

73 return parser(header, reader)