Coverage for src/galaxy_beep_frame/frame/state.py: 100%
24 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-31 04:18 +0200
« prev ^ index » next coverage.py v7.15.2, created at 2026-08-31 04:18 +0200
1"""FrameState class."""
3from dataclasses import InitVar, dataclass, field
4from typing import TYPE_CHECKING
6from galaxy_beep_frame.constant import (
7 CHANNEL_NUMBER_MAX,
8 CHANNEL_NUMBER_MIN,
9 MESSAGE_NUMBER_MAX,
10 MESSAGE_NUMBER_MIN,
11 SEQUENCE_NUMBER_MAX,
12 SEQUENCE_NUMBER_MIN,
13)
14from galaxy_beep_frame.exception.frame import (
15 AboveRangeError,
16 BelowRangeError,
17)
19from .header_type import HeaderType
21if TYPE_CHECKING:
22 from galaxy_beep_frame.header_type import PossibleHeaderType
24 from .base import Frame
25 from .header_type.continuation_indicator import (
26 ContinuationIndicator,
27 )
30@dataclass
31class FrameState:
32 """State of a BEEP frame."""
34 frame: Frame
35 header_type: HeaderType = field(init=False)
37 channel_number: int
38 message_number: int
39 sequence_number: int
41 answer_number: InitVar[int | None]
42 continuation_indicator: InitVar[ContinuationIndicator]
43 possible_header_type: InitVar[PossibleHeaderType]
45 def __post_init__(
46 self,
47 answer_number: int | None,
48 continuation_indicator: ContinuationIndicator,
49 possible_header_type: PossibleHeaderType,
50 ) -> None:
51 """Check numbers range."""
53 if self.channel_number < CHANNEL_NUMBER_MIN:
54 raise BelowRangeError(
55 self.channel_number,
56 CHANNEL_NUMBER_MIN,
57 "channel number",
58 )
59 if self.channel_number > CHANNEL_NUMBER_MAX:
60 raise AboveRangeError(
61 self.channel_number,
62 CHANNEL_NUMBER_MAX,
63 "channel number",
64 )
66 if self.message_number < MESSAGE_NUMBER_MIN:
67 raise BelowRangeError(
68 self.message_number,
69 MESSAGE_NUMBER_MIN,
70 "message number",
71 )
72 if self.message_number > MESSAGE_NUMBER_MAX:
73 raise AboveRangeError(
74 self.message_number,
75 MESSAGE_NUMBER_MAX,
76 "message number",
77 )
79 if self.sequence_number < SEQUENCE_NUMBER_MIN:
80 raise BelowRangeError(
81 self.sequence_number,
82 SEQUENCE_NUMBER_MIN,
83 "sequence number",
84 )
85 if self.sequence_number > SEQUENCE_NUMBER_MAX:
86 raise AboveRangeError(
87 self.sequence_number,
88 SEQUENCE_NUMBER_MAX,
89 "sequence number",
90 )
92 self.header_type = HeaderType.make(
93 state=self,
94 continuation_indicator=continuation_indicator,
95 possible_header_type=possible_header_type,
96 answer_number=answer_number,
97 )
99 def build(self, size: int) -> bytes:
100 """Build the header of this Frame."""
102 return self.header_type.build(size)