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
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-12 21:55 +0000
1from typing import Callable, Final, Mapping, Union
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)
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]
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}
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}")
73 return parser(header, reader)