diff --git a/vulnfeeds/models/metrics.go b/vulnfeeds/models/metrics.go index e8b9565ac9a..2befba51d4f 100644 --- a/vulnfeeds/models/metrics.go +++ b/vulnfeeds/models/metrics.go @@ -1,6 +1,7 @@ package models import ( + "encoding/json" "fmt" "log/slog" @@ -8,6 +9,7 @@ import ( "github.com/ossf/osv-schema/bindings/go/osvschema" ) +//nolint:recvcheck type ConversionOutcome int const ( @@ -36,8 +38,36 @@ var RefTagDenyList = []string{ "Broken Link", // Actively ignore these. } +var conversionOutcomeStrings = [...]string{ + "ConversionUnknown", "Successful", "Rejected", "NoSoftware", "NoRepos", "NoCommitRanges", "NoRanges", "FixUnresolvable", "Error", +} + func (c ConversionOutcome) String() string { - return [...]string{"ConversionUnknown", "Successful", "Rejected", "NoSoftware", "NoRepos", "NoCommitRanges", "NoRanges", "FixUnresolvable", "Error"}[c] + if int(c) >= 0 && int(c) < len(conversionOutcomeStrings) { + return conversionOutcomeStrings[c] + } + + return conversionOutcomeStrings[ConversionUnknown] +} + +func (c ConversionOutcome) MarshalJSON() ([]byte, error) { + return json.Marshal(c.String()) +} + +func (c *ConversionOutcome) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + for i, val := range conversionOutcomeStrings { + if val == s { + *c = ConversionOutcome(i) + + return nil + } + } + + return fmt.Errorf("invalid ConversionOutcome %q", s) } // ConversionMetrics holds the collected data about the conversion process for a single CVE.