Skip to content

Commit

Permalink
Merge pull request #21 from itchyny/improve-as-status
Browse files Browse the repository at this point in the history
Improve performance of status map parser
  • Loading branch information
lufia authored Oct 2, 2023
2 parents cea26f1 + 78b3761 commit 72e28ed
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 54 deletions.
86 changes: 43 additions & 43 deletions asstatusparse.go
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
package checkers

import (
"fmt"
"strings"
import "strings"

"golang.org/x/exp/slices"
)
type invalidStatusMapError string

var keywords = []string{"OK", "WARNING", "CRITICAL", "UNKNOWN"}
func (err invalidStatusMapError) Error() string {
return "invalid status map: " + string(err)
}

type duplicateStatusMapError Status

func (err duplicateStatusMapError) Error() string {
return "duplicate status in map: " + Status(err).String()
}

func strToStatus(s string) Status {
switch s {
case "OK":
return OK
case "WARNING":
return WARNING
case "CRITICAL":
return CRITICAL
case "UNKNOWN":
return UNKNOWN
func parseStatusPrefix(src string) (Status, string, bool) {
switch {
case strings.HasPrefix(src, "OK"):
return OK, src[len("OK"):], true
case strings.HasPrefix(src, "WARNING"):
return WARNING, src[len("WARNING"):], true
case strings.HasPrefix(src, "CRITICAL"):
return CRITICAL, src[len("CRITICAL"):], true
case strings.HasPrefix(src, "UNKNOWN"):
return UNKNOWN, src[len("UNKNOWN"):], true
default:
return OK, src, false
}
panic("invalid inputs.")
}

// Parse parses <status>=<status> notation string. <status> is one of:
// Parse parses a string of the form <status>=<status>. <status> is one of:
//
// - ok
// - warning
// - critical
// - unknown
//
// It can have multiple key-value pairs by comma.
func Parse(arg string) (map[Status]Status, error) {
if arg == "" {
return nil, nil
}

maps := make(map[Status]Status, 0)
args := strings.Split(arg, ",")

for _, s := range args {
if s == "" {
continue
// You can specify multiple key-value pairs separated by commas.
func Parse(src string) (map[Status]Status, error) {
orig, stm := src, map[Status]Status{}
for src = strings.ToUpper(src); src != ""; {
var from, to Status
var ok bool
if from, src, ok = parseStatusPrefix(src); !ok {
return nil, invalidStatusMapError(orig)
}
rawFrom, rawTo, found := strings.Cut(s, "=")
if !found {
return nil, fmt.Errorf("arguments is invalid : %v", s)
if src, ok = strings.CutPrefix(src, "="); !ok {
return nil, invalidStatusMapError(orig)
}
from := strings.ToUpper(rawFrom)
to := strings.ToUpper(rawTo)
if !slices.Contains(keywords, from) {
return nil, fmt.Errorf("from argument is invalid : %s", rawFrom)
if to, src, ok = parseStatusPrefix(src); !ok {
return nil, invalidStatusMapError(orig)
}
if !slices.Contains(keywords, to) {
return nil, fmt.Errorf("to argument is invalid : %s", rawTo)
if src, ok = strings.CutPrefix(src, ","); ok == (src == "") {
return nil, invalidStatusMapError(orig)
}
if _, ok := maps[strToStatus(from)]; ok {
return nil, fmt.Errorf("arguments is duplicate : %v", from)
if _, ok = stm[from]; ok {
return nil, duplicateStatusMapError(from)
}
maps[strToStatus(from)] = strToStatus(to)
stm[from] = to
}
return maps, nil
return stm, nil
}
28 changes: 25 additions & 3 deletions asstatusparse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ func TestParse(t *testing.T) {
},
},
{
name: "multi",
source: "unknown=critical,warning=critical",
name: "uppercase",
source: "UNKNOWN=CRITICAL",
expected: map[Status]Status{
UNKNOWN: CRITICAL,
},
},
{
name: "multi",
source: "unknown=ok,warning=critical",
expected: map[Status]Status{
UNKNOWN: OK,
WARNING: CRITICAL,
},
},
Expand All @@ -32,14 +39,29 @@ func TestParse(t *testing.T) {
source: "invalid=critical",
wantErr: true,
},
{
name: "= error",
source: "unknown critical",
wantErr: true,
},
{
name: "to error",
source: "critical=invalid",
wantErr: true,
},
{
name: "argument error",
source: "invalid=critical=invalid",
source: "unknown=critical=invalid",
wantErr: true,
},
{
name: "missing comma error",
source: "unknown=criticalwarning=critical",
wantErr: true,
},
{
name: "trailing comma error",
source: "unknown=ok,",
wantErr: true,
},
{
Expand Down
6 changes: 3 additions & 3 deletions checkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ const (

func (st Status) String() string {
switch st {
case 0:
case OK:
return "OK"
case 1:
case WARNING:
return "WARNING"
case 2:
case CRITICAL:
return "CRITICAL"
default:
return "UNKNOWN"
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
module github.com/mackerelio/checkers

go 1.18

require golang.org/x/exp v0.0.0-20230905200255-921286631fa9
go 1.20
2 changes: 0 additions & 2 deletions go.sum

This file was deleted.

0 comments on commit 72e28ed

Please sign in to comment.