func (e *Entry) UnmarshalJSON(raw []byte) error {
	var b *bool
	if json.Unmarshal(raw, &b) == nil && b != nil {
		*e = Bool(*b)
		return nil
	}
	var s *string
	if json.Unmarshal(raw, &s) == nil && s != nil {
		*e = String(*s)
		return nil
	}
	var i *int64
	if json.Unmarshal(raw, &i) == nil && i != nil {
		*e = Int64(*i)
		return nil
	}
	var u *uint64
	if json.Unmarshal(raw, &u) == nil && u != nil {
		*e = UInt64(*u)
		return nil
	}
	var f *float64
	if json.Unmarshal(raw, &f) == nil {
		if f != nil {
			*e = Float64(*f)
		} else {
			*e = Float64(math.NaN())
		}
		return nil
	}
	return fmt.Errorf("unable to parse %q as meta entry", raw)
}
UnmarshalJSON implements the "encoding/json".Unmarshaller interface.
package meta
import (
	"encoding/json"
	"fmt"
	"math"
)
type entryType int
const (
	_ entryType = iota
	metaStringType
	metaInt64Type
	metaUInt64Type
	metaFloat64Type
	metaBoolType
)
type Data map[string]Entry
func (d Data) Clone() Data {
	if d == nil {
		return nil
	}
	cpy := make(Data)
	for k, v := range d {
		cpy[k] = v
	}
	return cpy
}
type Entry struct {
	s string
	i int64
	u uint64
	f float64
	b bool
	typ entryType
}
func Bool(b bool) Entry { return Entry{b: b, typ: metaBoolType} }
func Float64(f float64) Entry { return Entry{f: f, typ: metaFloat64Type} }
func Int64(i int64) Entry { return Entry{i: i, typ: metaInt64Type} }
func UInt64(u uint64) Entry { return Entry{u: u, typ: metaUInt64Type} }
func String(s string) Entry { return Entry{s: s, typ: metaStringType} }
func (e Entry) Bool() (value, ok bool) { return e.b, e.typ == metaBoolType }
func (e Entry) Float64() (float64, bool) { return e.f, e.typ == metaFloat64Type }
func (e Entry) Int64() (int64, bool) { return e.i, e.typ == metaInt64Type }
func (e Entry) UInt64() (uint64, bool) { return e.u, e.typ == metaUInt64Type }
func (e Entry) String() string {
	switch e.typ {
	case metaBoolType:
		return fmt.Sprintf("%v", e.b)
	case metaFloat64Type:
		return fmt.Sprintf("%.15g", e.f)
	case metaInt64Type:
		return fmt.Sprintf("%v", e.i)
	case metaUInt64Type:
		return fmt.Sprintf("%v", e.u)
	case metaStringType:
		return e.s
	default:
		return fmt.Sprintf("%v", nil)
	}
}
func (e Entry) IsString() bool {
	return e.typ == metaStringType
}
func (e Entry) Interface() interface{} {
	switch e.typ {
	case metaBoolType:
		return e.b
	case metaFloat64Type:
		return e.f
	case metaInt64Type:
		return e.i
	case metaUInt64Type:
		return e.u
	case metaStringType:
		return e.s
	default:
		return nil
	}
}
func (e Entry) MarshalJSON() ([]byte, error) {
	switch e.typ {
	case metaBoolType:
		return json.Marshal(e.b)
	case metaFloat64Type:
		if math.IsNaN(e.f) {
			return json.Marshal(nil)
		}
		return json.Marshal(e.f)
	case metaInt64Type:
		return json.Marshal(e.i)
	case metaUInt64Type:
		return json.Marshal(e.u)
	case metaStringType:
		return json.Marshal(e.s)
	default:
		return json.Marshal(nil)
	}
}