refactor: Update parseWaypoints function to return error in schedule_parser_test.go
This commit is contained in:
@@ -17,7 +17,7 @@ const (
|
|||||||
|
|
||||||
Category = "category"
|
Category = "category"
|
||||||
CategoryArrival = "ARR"
|
CategoryArrival = "ARR"
|
||||||
FlightNumber = "number"
|
// FlightNumber = "number"
|
||||||
SSR = "ssr"
|
SSR = "ssr"
|
||||||
DepartureCode = "dep"
|
DepartureCode = "dep"
|
||||||
DepartureTime = "dep_time"
|
DepartureTime = "dep_time"
|
||||||
@@ -42,7 +42,7 @@ const (
|
|||||||
Route = "route"
|
Route = "route"
|
||||||
EstimatedTime = "estt"
|
EstimatedTime = "estt"
|
||||||
AlternateAirport = "alter"
|
AlternateAirport = "alter"
|
||||||
Register = "reg"
|
// Register = "reg"
|
||||||
PBN = "pbn"
|
PBN = "pbn"
|
||||||
NavigationEquipment = "nav"
|
NavigationEquipment = "nav"
|
||||||
EstimatedElapsedTime = "eet"
|
EstimatedElapsedTime = "eet"
|
||||||
@@ -50,21 +50,10 @@ const (
|
|||||||
PerformanceCategory = "per"
|
PerformanceCategory = "per"
|
||||||
RerouteInformation = "rif"
|
RerouteInformation = "rif"
|
||||||
Remarks = "remark"
|
Remarks = "remark"
|
||||||
Index = "idx"
|
// Index = "idx"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
categoryRegex = regexp.MustCompile(`\((?P<category>[A-Z]+)-`)
|
|
||||||
emptyLineRemove = regexp.MustCompile(`(?m)^\s*$`)
|
|
||||||
bodyOnly = regexp.MustCompile(`(.|\n)?(ZCZC(.|\n)*)NNNN(.|\n)?$`)
|
|
||||||
originator = regexp.MustCompile(`(?P<originatorDateTime>[0-9]+)\s(?P<originator>[A-Z]+)`)
|
|
||||||
navPattern = regexp.MustCompile(`(?m)NAV\/(?P<nav>.*)$`)
|
|
||||||
remarkPattern = regexp.MustCompile(`(?s)RMK\/(?P<remark>.*)`)
|
|
||||||
selPattern = regexp.MustCompile(`(?m)SEL\/(?P<sel>\w+)`)
|
|
||||||
pbnPattern = regexp.MustCompile(`(?m)PBN\/(?P<pbn>[A-Z0-9]+)`)
|
|
||||||
eetPattern = regexp.MustCompile(`(?s)(-?EET\/(?P<eet>(?:[A-Z]{4}\d{4}\s*)+))`)
|
|
||||||
performancePattern = regexp.MustCompile(`(?s)-?PER\/(?P<per>\w)`)
|
|
||||||
reroutePattern = regexp.MustCompile(`(?m)RIF\/(?P<rif>.*)[A-Z]{3}\/`)
|
|
||||||
otherPatterns = []*regexp.Regexp{navPattern, remarkPattern, selPattern, pbnPattern, eetPattern, performancePattern, reroutePattern}
|
otherPatterns = []*regexp.Regexp{navPattern, remarkPattern, selPattern, pbnPattern, eetPattern, performancePattern, reroutePattern}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package parsers
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
// String constants
|
||||||
|
const (
|
||||||
|
CANCELLED = "CNL"
|
||||||
|
AirportCode = "airport"
|
||||||
|
Date = "date"
|
||||||
|
Task = "task"
|
||||||
|
Index = "idx"
|
||||||
|
FlightNumber = "number"
|
||||||
|
Register = "reg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Regular expression patterns
|
||||||
|
const (
|
||||||
|
AllDigitsPattern = `^(?P<dep_time>\d+)$`
|
||||||
|
IndexPattern = `^(?P<idx>\(?L?[0-9]+\)?:?\.?)$`
|
||||||
|
DatePattern = `^(?P<date>\d{2}\w{3})$`
|
||||||
|
TaskPattern = `(?P<task>[A-Z]\/[A-Z])$`
|
||||||
|
WaypointPattern = `^(SI:)?(?P<arr_time>\d{4}(\(\d{2}[A-Z]{3}\))?)?\/?(?P<airport>[A-Z]{3})\/?(?P<dep_time>\d{4}(\(\d{2}[A-Z]{3}\))?)?$`
|
||||||
|
FlightNumberPattern = `^(?P<number>[0-9A-Z][0-9A-Z]\d{3,5}(\/\d+)*)$`
|
||||||
|
RegisterPattern = `^(?P<reg>B\d{4})$`
|
||||||
|
|
||||||
|
ArrPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>[A-Z0-9]+)(\/?(?P<ssr>[A-Z0-9]+))?-(?P<dep>[A-Z]{4})-(?P<arr>[A-Z]{4})(?P<arr_time>\d{4})\)$`
|
||||||
|
DepPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>[A-Z0-9]+)(\/(?P<ssr>[A-Z0-9]+))?-(?P<dep>[A-Z]{4})(?P<dep_time>\d{4})-(?P<arr>[A-Z]{4})\)$`
|
||||||
|
FplPatternString = `\((?P<category>[A-Z]{3})-(?P<number>[A-Z]+\d+)-(?P<indicator>[A-Z]{2})\n-(?P<aircraft>[A-Z]+\d+\/?[A-Z]?)\n?-(?P<surve>.*)\n?-(?P<dep>[A-Z]{4})(?P<dep_time>\d{4})\n?-(?P<speed>[A-Z]+\d+)(?P<level>[A-Z0-9]+)\s+(?P<route>(.|\n)+)\n-(?P<dest>[A-Z]{4})(?P<estt>\d{4})\s?(?P<alter>(\s[A-Z]{4})+)\n?-([A-Z]{3}\/(?:[A-Z]{4}\d{4}\s?)+)?(?P<other>(?m)[A-Z]{3}\/(.|\n)*)\)$`
|
||||||
|
CnlPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>\w+\d+)-?(?P<dep>[A-Z]{4})?-?(?<arr>[A-Z]{4})\)$`
|
||||||
|
DlaPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>\w+\d+)-?(?P<dep>[A-Z]{4})(?P<dep_time>\d{4})?-?(?<arr>[A-Z]{4})(?<arr_time>\d{4})?\)$`
|
||||||
|
)
|
||||||
|
|
||||||
|
// Compiled regular expressions
|
||||||
|
var (
|
||||||
|
AllDigitsExpression = regexp.MustCompile(AllDigitsPattern)
|
||||||
|
IndexExpression = regexp.MustCompile(IndexPattern)
|
||||||
|
TaskExpression = regexp.MustCompile(TaskPattern)
|
||||||
|
DateExpression = regexp.MustCompile(DatePattern)
|
||||||
|
WaypointExpression = regexp.MustCompile(WaypointPattern)
|
||||||
|
FlightNumberExpression = regexp.MustCompile(FlightNumberPattern)
|
||||||
|
RegisterExpression = regexp.MustCompile(RegisterPattern)
|
||||||
|
ArrPatternExpression = regexp.MustCompile(ArrPatternString)
|
||||||
|
DepPatternExpression = regexp.MustCompile(DepPatternString)
|
||||||
|
FplPatternExpression = regexp.MustCompile(FplPatternString)
|
||||||
|
CnlPatternExpression = regexp.MustCompile(CnlPatternString)
|
||||||
|
DlaPatternExpression = regexp.MustCompile(DlaPatternString)
|
||||||
|
BodyTypePattern = regexp.MustCompile(`^\(([A-Z]{3})(.*\n?)+\)$`)
|
||||||
|
|
||||||
|
categoryRegex = regexp.MustCompile(`\((?P<category>[A-Z]+)-`)
|
||||||
|
emptyLineRemove = regexp.MustCompile(`(?m)^\s*$`)
|
||||||
|
bodyOnly = regexp.MustCompile(`(.|\n)?(ZCZC(.|\n)*)NNNN(.|\n)?$`)
|
||||||
|
originator = regexp.MustCompile(`(?P<originatorDateTime>[0-9]+)\s(?P<originator>[A-Z]+)`)
|
||||||
|
navPattern = regexp.MustCompile(`(?m)NAV\/(?P<nav>.*)$`)
|
||||||
|
remarkPattern = regexp.MustCompile(`(?s)RMK\/(?P<remark>.*)`)
|
||||||
|
selPattern = regexp.MustCompile(`(?m)SEL\/(?P<sel>\w+)`)
|
||||||
|
pbnPattern = regexp.MustCompile(`(?m)PBN\/(?P<pbn>[A-Z0-9]+)`)
|
||||||
|
eetPattern = regexp.MustCompile(`(?s)(-?EET\/(?P<eet>(?:[A-Z]{4}\d{4}\s*)+))`)
|
||||||
|
performancePattern = regexp.MustCompile(`(?s)-?PER\/(?P<per>\w)`)
|
||||||
|
reroutePattern = regexp.MustCompile(`(?m)RIF\/(?P<rif>.*)[A-Z]{3}\/`)
|
||||||
|
)
|
||||||
@@ -24,46 +24,7 @@ type LineParser struct {
|
|||||||
Fields map[int]string
|
Fields map[int]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constants for specific values.
|
|
||||||
const (
|
|
||||||
CANCELLED = "CNL"
|
|
||||||
AirportCode = "airport"
|
|
||||||
Date = "date"
|
|
||||||
Task = "task"
|
|
||||||
// Index = "idx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Regular expression patterns.
|
|
||||||
const (
|
|
||||||
AllDigitsPattern = `^(?P<dep_time>\d+)$`
|
|
||||||
IndexPattern = `^(?P<idx>\(?L?[0-9]+\)?:?\.?)$`
|
|
||||||
DatePattern = `^(?P<date>\d{2}\w{3})$`
|
|
||||||
TaskPattern = `(?P<task>[A-Z]\/[A-Z])$`
|
|
||||||
WaypointPattern = `^(SI:)?(?P<arr_time>\d{4}(\(\d{2}[A-Z]{3}\))?)?\/?(?P<airport>[A-Z]{3})\/?(?P<dep_time>\d{4}(\(\d{2}[A-Z]{3}\))?)?$`
|
|
||||||
FlightNumberPattern = `^(?P<number>[0-9A-Z][0-9A-Z]\d{3,5}(\/\d+)*)$`
|
|
||||||
RegisterPattern = `^(?P<reg>B\d{4})$`
|
|
||||||
ArrPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>[A-Z0-9]+)(\/?(?P<ssr>[A-Z0-9]+))?-(?P<dep>[A-Z]{4})-(?P<arr>[A-Z]{4})(?P<arr_time>\d{4})\)$`
|
|
||||||
DepPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>[A-Z0-9]+)(\/(?P<ssr>[A-Z0-9]+))?-(?P<dep>[A-Z]{4})(?P<dep_time>\d{4})-(?P<arr>[A-Z]{4})\)$`
|
|
||||||
FplPatternString = `\((?P<category>[A-Z]{3})-(?P<number>[A-Z]+\d+)-(?P<indicator>[A-Z]{2})\n-(?P<aircraft>[A-Z]+\d+\/?[A-Z]?)\n?-(?P<surve>.*)\n?-(?P<dep>[A-Z]{4})(?P<dep_time>\d{4})\n?-(?P<speed>[A-Z]+\d+)(?P<level>[A-Z0-9]+)\s+(?P<route>(.|\n)+)\n-(?P<dest>[A-Z]{4})(?P<estt>\d{4})\s?(?P<alter>(\s[A-Z]{4})+)\n?-([A-Z]{3}\/(?:[A-Z]{4}\d{4}\s?)+)?(?P<other>(?m)[A-Z]{3}\/(.|\n)*)\)$`
|
|
||||||
CnlPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>\w+\d+)-?(?P<dep>[A-Z]{4})?-?(?<arr>[A-Z]{4})\)$`
|
|
||||||
DlaPatternString = `^\((?P<category>[A-Z]{3})-(?P<number>\w+\d+)-?(?P<dep>[A-Z]{4})(?P<dep_time>\d{4})?-?(?<arr>[A-Z]{4})(?<arr_time>\d{4})?\)$`
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Pre-compiled regular expressions.
|
|
||||||
AllDigitsExpression = regexp.MustCompile(AllDigitsPattern)
|
|
||||||
IndexExpression = regexp.MustCompile(IndexPattern)
|
|
||||||
TaskExpression = regexp.MustCompile(TaskPattern)
|
|
||||||
DateExpression = regexp.MustCompile(DatePattern)
|
|
||||||
WaypointExpression = regexp.MustCompile(WaypointPattern)
|
|
||||||
FlightNumberExpression = regexp.MustCompile(FlightNumberPattern)
|
|
||||||
RegisterExpression = regexp.MustCompile(RegisterPattern)
|
|
||||||
ArrPatternExpression = regexp.MustCompile(ArrPatternString)
|
|
||||||
DepPatternExpression = regexp.MustCompile(DepPatternString)
|
|
||||||
FplPatternExpression = regexp.MustCompile(FplPatternString)
|
|
||||||
CnlPatternExpression = regexp.MustCompile(CnlPatternString)
|
|
||||||
DlaPatternExpression = regexp.MustCompile(DlaPatternString)
|
|
||||||
BodyTypePattern = regexp.MustCompile(`^\(([A-Z]{3})(.*\n?)+\)$`)
|
|
||||||
bodyPatterns = map[string]BodyConfig{}
|
bodyPatterns = map[string]BodyConfig{}
|
||||||
parserMap = map[string]*regexp.Regexp{}
|
parserMap = map[string]*regexp.Regexp{}
|
||||||
parserDef = &[]LineParser{}
|
parserDef = &[]LineParser{}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package parsers
|
|||||||
import (
|
import (
|
||||||
"caatsm/internal/domain"
|
"caatsm/internal/domain"
|
||||||
"caatsm/pkg/utils"
|
"caatsm/pkg/utils"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -87,7 +88,7 @@ func ParseWithDef(line string, parserDef *LineParser) *domain.ScheduleLine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(words) > parserDef.WaypointStart {
|
if len(words) > parserDef.WaypointStart {
|
||||||
flightSchedule.Waypoints = parseWaypoints(words[parserDef.WaypointStart:])
|
flightSchedule.Waypoints, _ = parseWaypoints(words[parserDef.WaypointStart:])
|
||||||
} else {
|
} else {
|
||||||
log.Warn("No waypoints found")
|
log.Warn("No waypoints found")
|
||||||
flightSchedule.Comments = "No waypoints found"
|
flightSchedule.Comments = "No waypoints found"
|
||||||
@@ -96,81 +97,244 @@ func ParseWithDef(line string, parserDef *LineParser) *domain.ScheduleLine {
|
|||||||
return flightSchedule
|
return flightSchedule
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseLine(line string) *domain.ScheduleLine {
|
// func ParseLine(line string) *domain.ScheduleLine {
|
||||||
|
// log := utils.GetSugaredLogger()
|
||||||
|
// cleanLine := strings.TrimSpace(line)
|
||||||
|
// words := strings.Split(cleanLine, " ")
|
||||||
|
// var flightSchedule = &domain.ScheduleLine{
|
||||||
|
// Reference: line,
|
||||||
|
// }
|
||||||
|
// var data map[string]string
|
||||||
|
|
||||||
|
// if indexData := extract(words[0], IndexExpression); indexData != nil {
|
||||||
|
// flightSchedule.Index = indexData[Index]
|
||||||
|
// words = words[1:]
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Define the parsing strategy
|
||||||
|
// parseStrategy := []string{
|
||||||
|
// Task,
|
||||||
|
// Date,
|
||||||
|
// FlightNumber,
|
||||||
|
// Register,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Track parsed fields to avoid re-parsing
|
||||||
|
// parsed := make(map[string]bool)
|
||||||
|
// var maxParsed int
|
||||||
|
|
||||||
|
// // Parse each word in the line
|
||||||
|
// for i, word := range words {
|
||||||
|
// // Check if all fields have been parsed
|
||||||
|
// for _, name := range parseStrategy {
|
||||||
|
// // Skip if already parsed
|
||||||
|
// if parsed[name] {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// // Parse the word
|
||||||
|
// if data = extract(word, parserMap[name]); data != nil {
|
||||||
|
// // Update the flight schedule
|
||||||
|
// switch name {
|
||||||
|
// case Task:
|
||||||
|
// flightSchedule.Task = data[Task]
|
||||||
|
// parsed[Task] = true
|
||||||
|
// maxParsed = i
|
||||||
|
// case Date:
|
||||||
|
// flightSchedule.Date = data[Date]
|
||||||
|
// parsed[Date] = true
|
||||||
|
// maxParsed = i
|
||||||
|
// case FlightNumber:
|
||||||
|
// flightSchedule.FlightNumber = getFlightNumbers(data[FlightNumber])
|
||||||
|
// parsed[FlightNumber] = true
|
||||||
|
// maxParsed = i
|
||||||
|
// case Register:
|
||||||
|
// flightSchedule.AircraftReg = data[Register]
|
||||||
|
// parsed[Register] = true
|
||||||
|
// maxParsed = i
|
||||||
|
// }
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// if maxParsed+1 < len(words) {
|
||||||
|
// flightSchedule.Waypoints = parseWaypoints(words[maxParsed+1:])
|
||||||
|
// } else {
|
||||||
|
// log.Warn("No waypoints found")
|
||||||
|
// flightSchedule.Comments = "No waypoints found"
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return flightSchedule
|
||||||
|
// }
|
||||||
|
// func ParseLine(line string) *domain.ScheduleLine {
|
||||||
|
// log := utils.GetSugaredLogger()
|
||||||
|
// cleanLine := strings.TrimSpace(line)
|
||||||
|
// words := strings.Split(cleanLine, " ")
|
||||||
|
// flightSchedule := &domain.ScheduleLine{Reference: line}
|
||||||
|
|
||||||
|
// if indexData := extract(words[0], IndexExpression); indexData != nil {
|
||||||
|
// flightSchedule.Index = indexData[Index]
|
||||||
|
// words = words[1:]
|
||||||
|
// }
|
||||||
|
|
||||||
|
// parseStrategy := []string{Task, Date, FlightNumber, Register}
|
||||||
|
// _, maxParsed := parseFields(words, parseStrategy, flightSchedule)
|
||||||
|
|
||||||
|
// if maxParsed+1 < len(words) {
|
||||||
|
// flightSchedule.Waypoints = parseWaypoints(words[maxParsed+1:])
|
||||||
|
// } else {
|
||||||
|
// log.Warn("No waypoints found")
|
||||||
|
// flightSchedule.Comments = "No waypoints found"
|
||||||
|
// }
|
||||||
|
// return flightSchedule
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func parseFields(words []string, parseStrategy []string, flightSchedule *domain.ScheduleLine) (map[string]bool, int) {
|
||||||
|
// parsed := make(map[string]bool)
|
||||||
|
// var maxParsed int
|
||||||
|
|
||||||
|
// for i, word := range words {
|
||||||
|
// for _, name := range parseStrategy {
|
||||||
|
// if parsed[name] {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// if data := extract(word, parserMap[name]); data != nil {
|
||||||
|
// updateFlightSchedule(flightSchedule, name, data)
|
||||||
|
// parsed[name] = true
|
||||||
|
// maxParsed = i
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return parsed, maxParsed
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func updateFlightSchedule(flightSchedule *domain.ScheduleLine, name string, data map[string]string) {
|
||||||
|
// switch name {
|
||||||
|
// case Task:
|
||||||
|
// flightSchedule.Task = data[Task]
|
||||||
|
// case Date:
|
||||||
|
// flightSchedule.Date = data[Date]
|
||||||
|
// case FlightNumber:
|
||||||
|
// flightSchedule.FlightNumber = getFlightNumbers(data[FlightNumber])
|
||||||
|
// case Register:
|
||||||
|
// flightSchedule.AircraftReg = data[Register]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func parseWaypoints(points []string) []domain.WayPoint {
|
||||||
|
// log := utils.GetSugaredLogger()
|
||||||
|
// if len(points) == 0 {
|
||||||
|
// log.Warn("No waypoints found")
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //find first waypoint
|
||||||
|
// var realWaypoints []string
|
||||||
|
// for i, point := range points {
|
||||||
|
// if extract(point, WaypointExpression) != nil {
|
||||||
|
// realWaypoints = points[i:]
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if len(realWaypoints) == 0 {
|
||||||
|
// log.Warn("No waypoints found")
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
// var waypoints []domain.WayPoint
|
||||||
|
// for i, point := range realWaypoints {
|
||||||
|
// // log.Debugf("Parsing waypoint: %s", point)
|
||||||
|
// // check the next point for departure time
|
||||||
|
// if digits := extract(point, AllDigitsExpression); i > 0 && digits != nil {
|
||||||
|
// // if the previous point was a waypoint, update the departure time
|
||||||
|
// if l := len(waypoints); l > 0 {
|
||||||
|
// waypoints[l-1].DepartureTime = digits[DepartureTime]
|
||||||
|
// }
|
||||||
|
// } else if waypoint := ExtractWaypoint(point); waypoint != nil {
|
||||||
|
// // log.Debugf("Waypoint: %v", waypoint)
|
||||||
|
// waypoints = append(waypoints, *waypoint)
|
||||||
|
// } else {
|
||||||
|
// log.Warnf("Failed to parse waypoint: %s", point)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // log.Debugf("Found %d waypoints", len(waypoints))
|
||||||
|
// return waypoints
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ParseLine processes a single line of schedule data and returns a ScheduleLine object.
|
||||||
|
func ParseLine(line string) (*domain.ScheduleLine, error) {
|
||||||
log := utils.GetSugaredLogger()
|
log := utils.GetSugaredLogger()
|
||||||
cleanLine := strings.TrimSpace(line)
|
cleanLine := strings.TrimSpace(line)
|
||||||
words := strings.Split(cleanLine, " ")
|
words := strings.Split(cleanLine, " ")
|
||||||
var flightSchedule = &domain.ScheduleLine{
|
flightSchedule := &domain.ScheduleLine{Reference: line}
|
||||||
Reference: line,
|
|
||||||
}
|
|
||||||
var data map[string]string
|
|
||||||
|
|
||||||
if indexData := extract(words[0], IndexExpression); indexData != nil {
|
if indexData := extract(words[0], IndexExpression); indexData != nil {
|
||||||
flightSchedule.Index = indexData[Index]
|
flightSchedule.Index = indexData[Index]
|
||||||
words = words[1:]
|
words = words[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the parsing strategy
|
parseStrategy := []string{Task, Date, FlightNumber, Register}
|
||||||
parseStrategy := []string{
|
_, maxParsed, err := parseFields(words, parseStrategy, flightSchedule)
|
||||||
Task,
|
if err != nil {
|
||||||
Date,
|
return nil, err
|
||||||
FlightNumber,
|
|
||||||
Register,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track parsed fields to avoid re-parsing
|
// Check if there are any waypoints after the parsed fields
|
||||||
parsed := make(map[string]bool)
|
|
||||||
var maxParsed int
|
|
||||||
|
|
||||||
// Parse each word in the line
|
|
||||||
for i, word := range words {
|
|
||||||
// Check if all fields have been parsed
|
|
||||||
for _, name := range parseStrategy {
|
|
||||||
// Skip if already parsed
|
|
||||||
if parsed[name] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Parse the word
|
|
||||||
if data = extract(word, parserMap[name]); data != nil {
|
|
||||||
// Update the flight schedule
|
|
||||||
switch name {
|
|
||||||
case Task:
|
|
||||||
flightSchedule.Task = data[Task]
|
|
||||||
parsed[Task] = true
|
|
||||||
maxParsed = i
|
|
||||||
case Date:
|
|
||||||
flightSchedule.Date = data[Date]
|
|
||||||
parsed[Date] = true
|
|
||||||
maxParsed = i
|
|
||||||
case FlightNumber:
|
|
||||||
flightSchedule.FlightNumber = getFlightNumbers(data[FlightNumber])
|
|
||||||
parsed[FlightNumber] = true
|
|
||||||
maxParsed = i
|
|
||||||
case Register:
|
|
||||||
flightSchedule.AircraftReg = data[Register]
|
|
||||||
parsed[Register] = true
|
|
||||||
maxParsed = i
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if maxParsed+1 < len(words) {
|
if maxParsed+1 < len(words) {
|
||||||
flightSchedule.Waypoints = parseWaypoints(words[maxParsed+1:])
|
waypoints, err := parseWaypoints(words[maxParsed+1:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
flightSchedule.Waypoints = waypoints
|
||||||
} else {
|
} else {
|
||||||
log.Warn("No waypoints found")
|
log.Warn("No waypoints found")
|
||||||
flightSchedule.Comments = "No waypoints found"
|
flightSchedule.Comments = "No waypoints found"
|
||||||
}
|
}
|
||||||
|
|
||||||
return flightSchedule
|
return flightSchedule, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseWaypoints(points []string) []domain.WayPoint {
|
// parseFields processes the fields based on the given strategy and updates the flight schedule.
|
||||||
|
func parseFields(words []string, parseStrategy []string, flightSchedule *domain.ScheduleLine) (map[string]bool, int, error) {
|
||||||
|
parsed := make(map[string]bool)
|
||||||
|
var maxParsed int
|
||||||
|
|
||||||
|
for i, word := range words {
|
||||||
|
for _, name := range parseStrategy {
|
||||||
|
if parsed[name] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if data := extract(word, parserMap[name]); data != nil {
|
||||||
|
updateFlightSchedule(flightSchedule, name, data)
|
||||||
|
parsed[name] = true
|
||||||
|
maxParsed = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsed, maxParsed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateFlightSchedule updates the flight schedule based on the parsed data.
|
||||||
|
func updateFlightSchedule(flightSchedule *domain.ScheduleLine, name string, data map[string]string) {
|
||||||
|
switch name {
|
||||||
|
case Task:
|
||||||
|
flightSchedule.Task = data[Task]
|
||||||
|
case Date:
|
||||||
|
flightSchedule.Date = data[Date]
|
||||||
|
case FlightNumber:
|
||||||
|
flightSchedule.FlightNumber = getFlightNumbers(data[FlightNumber])
|
||||||
|
case Register:
|
||||||
|
flightSchedule.AircraftReg = data[Register]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseWaypoints processes a slice of waypoint strings and returns a slice of WayPoint objects.
|
||||||
|
func parseWaypoints(points []string) ([]domain.WayPoint, error) {
|
||||||
log := utils.GetSugaredLogger()
|
log := utils.GetSugaredLogger()
|
||||||
if len(points) == 0 {
|
if len(points) == 0 {
|
||||||
log.Warn("No waypoints found")
|
log.Warn("No waypoints found")
|
||||||
return nil
|
return nil, errors.New("no waypoints")
|
||||||
}
|
}
|
||||||
|
|
||||||
//find first waypoint
|
//find first waypoint
|
||||||
@@ -183,7 +347,7 @@ func parseWaypoints(points []string) []domain.WayPoint {
|
|||||||
}
|
}
|
||||||
if len(realWaypoints) == 0 {
|
if len(realWaypoints) == 0 {
|
||||||
log.Warn("No waypoints found")
|
log.Warn("No waypoints found")
|
||||||
return nil
|
return nil, errors.New("no waypoints")
|
||||||
}
|
}
|
||||||
var waypoints []domain.WayPoint
|
var waypoints []domain.WayPoint
|
||||||
for i, point := range realWaypoints {
|
for i, point := range realWaypoints {
|
||||||
@@ -202,7 +366,7 @@ func parseWaypoints(points []string) []domain.WayPoint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// log.Debugf("Found %d waypoints", len(waypoints))
|
// log.Debugf("Found %d waypoints", len(waypoints))
|
||||||
return waypoints
|
return waypoints, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -178,7 +178,8 @@ var _ = Describe("Schedule Parser", func() {
|
|||||||
Context("XIY/0415 TSN/0645 CGQ", func() {
|
Context("XIY/0415 TSN/0645 CGQ", func() {
|
||||||
It("should return 3 waypoints", func() {
|
It("should return 3 waypoints", func() {
|
||||||
points := strings.Split("XIY/0415 TSN/0645 CGQ", " ")
|
points := strings.Split("XIY/0415 TSN/0645 CGQ", " ")
|
||||||
waypoints := parseWaypoints(points)
|
waypoints, err := parseWaypoints(points)
|
||||||
|
Expect(Expect(err).NotTo(HaveOccurred()))
|
||||||
Expect(waypoints).NotTo(BeNil())
|
Expect(waypoints).NotTo(BeNil())
|
||||||
Expect(waypoints).To(HaveLen(3))
|
Expect(waypoints).To(HaveLen(3))
|
||||||
Expect(waypoints[0].Airport).To(Equal("XIY"))
|
Expect(waypoints[0].Airport).To(Equal("XIY"))
|
||||||
@@ -192,7 +193,8 @@ var _ = Describe("Schedule Parser", func() {
|
|||||||
Context("ICN 0235 TSN", func() {
|
Context("ICN 0235 TSN", func() {
|
||||||
It("should return 2 waypoints", func() {
|
It("should return 2 waypoints", func() {
|
||||||
points := strings.Split("ICN 0235 TSN", " ")
|
points := strings.Split("ICN 0235 TSN", " ")
|
||||||
waypoints := parseWaypoints(points)
|
waypoints, err := parseWaypoints(points)
|
||||||
|
Expect(Expect(err).NotTo(HaveOccurred()))
|
||||||
Expect(waypoints).NotTo(BeNil())
|
Expect(waypoints).NotTo(BeNil())
|
||||||
Expect(waypoints).To(HaveLen(2))
|
Expect(waypoints).To(HaveLen(2))
|
||||||
Expect(waypoints[0].Airport).To(Equal("ICN"))
|
Expect(waypoints[0].Airport).To(Equal("ICN"))
|
||||||
|
|||||||
Reference in New Issue
Block a user