Files
go-caatsm/internal/parsers/aviation_parser.go
T
windyboy b9e021d3ab refactor: Update AFTN message parsing logic
The code changes in `aviation_parser_test.go` update the AFTN message parsing logic. The `ParseHeader` function now returns an additional error value, allowing for better error handling. The tests have been updated to reflect this change, ensuring that the parsing function handles errors correctly. This refactor improves the reliability and maintainability of the AFTN message parsing functionality.
2024-07-20 18:55:28 +08:00

109 lines
3.4 KiB
Go

package parsers
import (
"caatsm/internal/domain"
"errors" // Import errors package to handle errors
"strings"
)
const (
StartIndicatorPrefix = "ZCZC"
EndHeaderMarker = "."
BeginPartMarker = "BEGIN PART"
)
// ParseHeader parses the header of the message and returns a ParsedMessage struct
func ParseHeader(fullMessage string) (domain.ParsedMessage, error) {
fullMessage = strings.TrimSpace(fullMessage) // Trim leading and trailing spaces
lines := strings.Split(fullMessage, "\n") // Split the message into lines
// Parse the start indicator line
startIndicator, messageID, dateTime, err := parseStartIndicator(lines[0])
if err != nil {
return domain.ParsedMessage{}, err // Return error if parsing fails
}
// Parse the priority indicator and primary address line
priorityIndicator, primaryAddress, err := parsePriorityAndPrimary(lines[1])
if err != nil {
return domain.ParsedMessage{}, err // Return error if parsing fails
}
// Parse the remaining lines
secondaryAddresses, originator, originatorDateTime, bodyAndFooter := parseRemainingLines(lines[2:])
// Return the parsed message as a domain.ParsedMessage struct
return domain.ParsedMessage{
StartIndicator: startIndicator,
MessageID: messageID,
DateTime: dateTime,
PriorityIndicator: priorityIndicator,
PrimaryAddress: primaryAddress,
SecondaryAddresses: secondaryAddresses,
Originator: originator,
OriginatorDateTime: originatorDateTime,
BodyAndFooter: bodyAndFooter,
}, nil
}
// parseStartIndicator parses the start indicator line
func parseStartIndicator(line string) (string, string, string, error) {
if strings.HasPrefix(line, StartIndicatorPrefix) {
parts := strings.Fields(line)
if len(parts) >= 3 {
return parts[0], parts[1], parts[2], nil
}
}
return "", "", "", errors.New("invalid start indicator line format")
}
// parsePriorityAndPrimary parses the priority indicator and primary address line
func parsePriorityAndPrimary(line string) (string, string, error) {
parts := strings.Fields(line)
if len(parts) >= 2 {
return parts[0], parts[1], nil
}
return "", "", errors.New("invalid priority indicator line format")
}
// parseRemainingLines parses the remaining lines of the message
func parseRemainingLines(lines []string) ([]string, string, string, string) {
var (
secondaryAddresses []string
originator string
originatorDateTime string
bodyAndFooter strings.Builder
headerEnded bool
)
for _, line := range lines {
line = strings.TrimSpace(line)
if headerEnded {
// Append line to body and footer if header has ended
bodyAndFooter.WriteString(line + "\n")
} else {
switch {
case line == EndHeaderMarker:
// Ignore end header marker
case strings.HasPrefix(line, "."):
// Parse originator and originatorDateTime
originatorInfo := strings.Fields(line[1:])
if len(originatorInfo) >= 2 {
originator = originatorInfo[0]
originatorDateTime = originatorInfo[1]
}
headerEnded = true
case strings.HasPrefix(line, BeginPartMarker) || strings.HasPrefix(line, "("):
// Mark header as ended and append line to body and footer
headerEnded = true
bodyAndFooter.WriteString(line + "\n")
default:
// Append line to secondary addresses
secondaryAddresses = append(secondaryAddresses, line)
}
}
}
return secondaryAddresses, originator, originatorDateTime, bodyAndFooter.String()
}