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  }