Architecture#

        ---
title: Frame architecture
---
classDiagram
 Frame *-- FrameState : state
 FrameState *-- HeaderType : header_type
 Answer --|> HeaderType
 Error --|> HeaderType
 Message --|> HeaderType
 Null --|> HeaderType
 Reply --|> HeaderType
 Frame ..> PossibleHeaderType : used during initialization
 FrameState ..> PossibleHeaderType : used during initialization
 HeaderType ..> PossibleHeaderType : used to make the corresponding object
 Frame ..> ContinuationIndicator : used during initialization
 FrameState ..> ContinuationIndicator : used during initialization
 HeaderType ..> ContinuationIndicator : used in make
 Answer ..> ContinuationIndicator : continuation_indicator
 Error ..> ContinuationIndicator : continuation_indicator
 Message ..> ContinuationIndicator : continuation_indicator
 Reply ..> ContinuationIndicator : continuation_indicator
 class ContinuationIndicator {
     <<Enumeration>>
     COMPLETE
     INTERMEDIATE
 }
 class PossibleHeaderType {
     <<Enumeration>>
     ANS
     ERR
     MSG
     NUL
     RPY
 }
 class Frame {
     +bytes payload
     +FrameState state
     +bytes build()
     +Frame(payload: bytes, channel_number: int, message_number: int, sequence_number: int, answer_number: int | None, continuation_indicator: ContinuationIndicator, possible_header_type: PossibleHeaderType)
 }
 class FrameState {
     +Frame frame
     +HeaderType header_type
     +int channel_number
     +int message_number
     +int sequence_number
     +bytes build()
     +FrameState(frame: Frame, channel_number: int, message_number: int, sequence_number: int, answer_number: int | None, continuation_indicator: ContinuationIndicator, possible_header_type: PossibleHeaderType)
 }
 class HeaderType {
     +FrameState state
     +bytes build()
     +HeaderType make(state: FrameState, continuation_indicator: ContinuationIndicator, possible_header_type: PossibleHeaderType, answer_number: int | None)$
     +HeaderType(state:FrameState)
 }
 class Answer {
     +int answer_number
     +ContinuationIndicator continuation_indicator
     +Answer(state: FrameState, answer_number: int, continuation_indicator: ContinuationIndicator)
 }
 class Error {
     +ContinuationIndicator continuation_indicator
     +Error(state: FrameState, continuation_indicator: ContinuationIndicator)
 }
 class Message {
     +ContinuationIndicator continuation_indicator
     +Message(state: FrameState, continuation_indicator: ContinuationIndicator)
 }
 class Null {}
 class Reply {
     +ContinuationIndicator continuation_indicator
     +Reply(state: FrameState, continuation_indicator: ContinuationIndicator)
 }
    

State#

This library use class as state. A Frame class can have different header. Instead of creating multiple class like MessageFrame, AnswerFrame, etc. I chose to store the header as a state of Frame (FrameState being the state holder and manager). As each state can have different behaviors, any behaviors dependents of the header must be defined in the specific HeaderType.