mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
106 lines
3.8 KiB
Go
106 lines
3.8 KiB
Go
// Copyright [2019] LinkedIn Corp. Licensed under the Apache License, Version
|
|
// 2.0 (the "License"); you may not use this file except in compliance with the
|
|
// License. You may obtain a copy of the License at
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
package goavro
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// enum does not have child objects, therefore whatever namespace it defines is
|
|
// just to store its name in the symbol table.
|
|
func makeEnumCodec(st map[string]*Codec, enclosingNamespace string, schemaMap map[string]interface{}) (*Codec, error) {
|
|
c, err := registerNewCodec(st, schemaMap, enclosingNamespace)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Enum ought to have valid name: %s", err)
|
|
}
|
|
|
|
// enum type must have symbols
|
|
s1, ok := schemaMap["symbols"]
|
|
if !ok {
|
|
return nil, fmt.Errorf("Enum %q ought to have symbols key", c.typeName)
|
|
}
|
|
s2, ok := s1.([]interface{})
|
|
if !ok || len(s2) == 0 {
|
|
return nil, fmt.Errorf("Enum %q symbols ought to be non-empty array of strings: %v", c.typeName, s1)
|
|
}
|
|
symbols := make([]string, len(s2))
|
|
for i, s := range s2 {
|
|
symbol, ok := s.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("Enum %q symbol %d ought to be non-empty string; received: %T", c.typeName, i+1, symbol)
|
|
}
|
|
if err := checkString(symbol); err != nil {
|
|
return nil, fmt.Errorf("Enum %q symbol %d ought to %s", c.typeName, i+1, err)
|
|
}
|
|
symbols[i] = symbol
|
|
}
|
|
|
|
c.nativeFromBinary = func(buf []byte) (interface{}, []byte, error) {
|
|
var value interface{}
|
|
var err error
|
|
var index int64
|
|
|
|
if value, buf, err = longNativeFromBinary(buf); err != nil {
|
|
return nil, nil, fmt.Errorf("cannot decode binary enum %q index: %s", c.typeName, err)
|
|
}
|
|
index = value.(int64)
|
|
if index < 0 || index >= int64(len(symbols)) {
|
|
return nil, nil, fmt.Errorf("cannot decode binary enum %q: index ought to be between 0 and %d; read index: %d", c.typeName, len(symbols)-1, index)
|
|
}
|
|
return symbols[index], buf, nil
|
|
}
|
|
c.binaryFromNative = func(buf []byte, datum interface{}) ([]byte, error) {
|
|
someString, ok := datum.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("cannot encode binary enum %q: expected string; received: %T", c.typeName, datum)
|
|
}
|
|
for i, symbol := range symbols {
|
|
if symbol == someString {
|
|
return longBinaryFromNative(buf, i)
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("cannot encode binary enum %q: value ought to be member of symbols: %v; %q", c.typeName, symbols, someString)
|
|
}
|
|
c.nativeFromTextual = func(buf []byte) (interface{}, []byte, error) {
|
|
if buf, _ = advanceToNonWhitespace(buf); len(buf) == 0 {
|
|
return nil, nil, fmt.Errorf("cannot decode textual enum: %s", io.ErrShortBuffer)
|
|
}
|
|
// decode enum string
|
|
var value interface{}
|
|
var err error
|
|
value, buf, err = stringNativeFromTextual(buf)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("cannot decode textual enum: expected key: %s", err)
|
|
}
|
|
someString := value.(string)
|
|
for _, symbol := range symbols {
|
|
if symbol == someString {
|
|
return someString, buf, nil
|
|
}
|
|
}
|
|
return nil, nil, fmt.Errorf("cannot decode textual enum %q: value ought to be member of symbols: %v; %q", c.typeName, symbols, someString)
|
|
}
|
|
c.textualFromNative = func(buf []byte, datum interface{}) ([]byte, error) {
|
|
someString, ok := datum.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf("cannot encode textual enum %q: expected string; received: %T", c.typeName, datum)
|
|
}
|
|
for _, symbol := range symbols {
|
|
if symbol == someString {
|
|
return stringTextualFromNative(buf, someString)
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("cannot encode textual enum %q: value ought to be member of symbols: %v; %q", c.typeName, symbols, someString)
|
|
}
|
|
|
|
return c, nil
|
|
}
|