package bus import ( "fmt" "strings" "github.com/tgckpg/golifehk/utils" ) type QueryObject struct { Route string BusStops *[]BusStop } type QueryResult struct { BusStops []BusStop err string } type Term struct { Value string ProblyRoute bool } func Query( message string ) *QueryResult { return &QueryResult{ err: "No Result" } } func test( entry BusStop, val string ) bool { switch true { case strings.Contains( entry.Name_zhant, val ): fallthrough case strings.Contains( entry.Name_en, val ): return true } return false } func parse( line string ) ( *QueryObject, error ) { busStops, err := getBusStops() if err != nil { return nil, err } var route string = "" var searches = []string{} matches := []BusStop{} // Sanitize and assume properties for each of the keywords terms := []Term{} for _, val := range strings.Split( line, " " ) { val = strings.ToUpper( strings.Trim( val, " " ) ) term := Term{ Value: val, ProblyRoute: strings.ContainsAny( val, utils.ROUTE_CHARS ), } terms = append( terms, term ) } // Search for route name first, otherwise search in other props for _, entry := range *busStops { // Search for RouteId for _, term := range terms { if term.ProblyRoute && term.Value == entry.RouteId { if route != "" && route != term.Value { return nil, fmt.Errorf( "Cannot %s & %s", route, term.Value ) } matches = append( matches, entry ) route = entry.RouteId break } searches = append( searches, term.Value ) if test( entry, term.Value ) { matches = append( matches, entry ) break } } } // If route found, filter out all other route // then search within that route if route != "" && 0 < len( searches ) { matches_in := []BusStop{} for _, entry := range matches { if entry.RouteId != route { continue } for _, val := range searches { if test( entry, val ) { matches_in = append( matches_in, entry ) break } } } matches = matches_in } return &QueryObject{ Route: route, BusStops: &matches }, err }