github.com/grailbio/base@v0.0.11/eventlog/internal/marshal/marshal.go (about) 1 // Copyright 2020 GRAIL, Inc. All rights reserved. 2 // Use of this source code is governed by the Apache 2.0 3 // license that can be found in the LICENSE file. 4 5 package marshal 6 7 import ( 8 "encoding/json" 9 "fmt" 10 ) 11 12 // eventTypeFieldKey is the name of the JSON member holding the event type, 13 // passed as typ, in the JSON string returned by marshal. It is a reserved field 14 // key name. 15 const eventTypeFieldKey = "eventType" 16 17 // marshal marshal event information into a JSON string. Field keys must be 18 // unique, otherwise marshal returns an error. 19 func Marshal(typ string, fieldPairs []interface{}) (string, error) { 20 if len(fieldPairs)%2 != 0 { 21 return "", fmt.Errorf("len(fieldPairs) must be even; %d is not even", len(fieldPairs)) 22 } 23 fields := make(map[string]interface{}) 24 for i := 0; i < len(fieldPairs); i++ { 25 key, isString := fieldPairs[i].(string) 26 if !isString { 27 return "", fmt.Errorf("field key at fieldPairs[%d] must be a string: %v", i, fieldPairs[i]) 28 } 29 if key == eventTypeFieldKey { 30 return "", fmt.Errorf("field key at fieldPairs[%d] is '%s'; '%s' is reserved", i, eventTypeFieldKey, eventTypeFieldKey) 31 } 32 if _, dupKey := fields[key]; dupKey { 33 return "", fmt.Errorf("key %q at fieldPairs[%d] already used; duplicate keys not allowed", key, i) 34 } 35 i++ 36 fields[key] = fieldPairs[i] 37 } 38 fields[eventTypeFieldKey] = typ 39 bs, err := json.Marshal(fields) 40 if err != nil { 41 return "", fmt.Errorf("error marshaling fields to JSON: %v", err) 42 } 43 return string(bs), nil 44 }