// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package keys

import (
	
	
	

	
)

// Value is a [label.Key] for untyped values.
type Value struct {
	name        string
	description string
}

// New creates a new Key for untyped values.
func (,  string) *Value {
	return &Value{name: , description: }
}

func ( *Value) () string        { return .name }
func ( *Value) () string { return .description }

func ( *Value) ( []byte,  label.Label) []byte {
	return fmt.Append(, .From())
}

// Get returns the label for the key of a label.Map.
func ( *Value) ( label.Map) any {
	if  := .Find(); .Valid() {
		return .From()
	}
	return nil
}

// From returns the value of a Label.
func ( *Value) ( label.Label) any { return .UnpackValue() }

// Of creates a new Label with this key and the supplied value.
func ( *Value) ( any) label.Label { return label.OfValue(, ) }

// Tag represents a key for tagging labels that have no value.
// These are used when the existence of the label is the entire information it
// carries, such as marking events to be of a specific kind, or from a specific
// package.
type Tag struct {
	name        string
	description string
}

// NewTag creates a new [label.Key] for tagging labels.
func (,  string) *Tag {
	return &Tag{name: , description: }
}

func ( *Tag) () string        { return .name }
func ( *Tag) () string { return .description }

func ( *Tag) ( []byte,  label.Label) []byte { return  }

// New creates a new Label with this key.
func ( *Tag) () label.Label { return label.OfValue(, nil) }

// Int is a [label.Key] for signed integers.
type Int struct {
	name        string
	description string
}

// NewInt returns a new [label.Key] for int64 values.
func (,  string) *Int {
	return &Int{name: , description: }
}

func ( *Int) () string        { return .name }
func ( *Int) () string { return .description }

func ( *Int) ( []byte,  label.Label) []byte {
	return strconv.AppendInt(, .From(), 10)
}

// Of creates a new Label with this key and the supplied value.
func ( *Int) ( int) label.Label { return .Of64(int64()) }

// Of64 creates a new Label with this key and the supplied value.
func ( *Int) ( int64) label.Label { return label.Of64(, uint64()) }

// Get returns the label for the key of a label.Map.
func ( *Int) ( label.Map) int64 {
	if  := .Find(); .Valid() {
		return .From()
	}
	return 0
}

// From returns the value of a Label.
func ( *Int) ( label.Label) int64 { return int64(.Unpack64()) }

// Uint is a [label.Key] for unsigned integers.
type Uint struct {
	name        string
	description string
}

// NewUint creates a new [label.Key] for unsigned values.
func (,  string) *Uint {
	return &Uint{name: , description: }
}

func ( *Uint) () string        { return .name }
func ( *Uint) () string { return .description }

func ( *Uint) ( []byte,  label.Label) []byte {
	return strconv.AppendUint(, .From(), 10)
}

// Of creates a new Label with this key and the supplied value.
func ( *Uint) ( uint64) label.Label { return label.Of64(, ) }

// Get returns the label for the key of a label.Map.
func ( *Uint) ( label.Map) uint64 {
	if  := .Find(); .Valid() {
		return .From()
	}
	return 0
}

// From returns the value of a Label.
func ( *Uint) ( label.Label) uint64 { return .Unpack64() }

// Float is a label.Key for floating-point values.
type Float struct {
	name        string
	description string
}

// NewFloat creates a new [label.Key] for floating-point values.
func (,  string) *Float {
	return &Float{name: , description: }
}

func ( *Float) () string        { return .name }
func ( *Float) () string { return .description }

func ( *Float) ( []byte,  label.Label) []byte {
	return strconv.AppendFloat(, .From(), 'E', -1, 64)
}

// Of creates a new Label with this key and the supplied value.
func ( *Float) ( float64) label.Label {
	return label.Of64(, math.Float64bits())
}

// Get returns the label for the key of a label.Map.
func ( *Float) ( label.Map) float64 {
	if  := .Find(); .Valid() {
		return .From()
	}
	return 0
}

// From returns the value of a Label.
func ( *Float) ( label.Label) float64 {
	return math.Float64frombits(.Unpack64())
}

// String represents a key
type String struct {
	name        string
	description string
}

// NewString creates a new Key for int64 values.
func (,  string) *String {
	return &String{name: , description: }
}

func ( *String) () string        { return .name }
func ( *String) () string { return .description }

func ( *String) ( []byte,  label.Label) []byte {
	return strconv.AppendQuote(, .From())
}

// Of creates a new Label with this key and the supplied value.
func ( *String) ( string) label.Label { return label.OfString(, ) }

// Get returns the label for the key of a label.Map.
func ( *String) ( label.Map) string {
	if  := .Find(); .Valid() {
		return .From()
	}
	return ""
}

// From returns the value of a Label.
func ( *String) ( label.Label) string { return .UnpackString() }

// Error represents a key
type Error struct {
	name        string
	description string
}

// NewError returns a new [label.Key] for error values.
func (,  string) *Error {
	return &Error{name: , description: }
}

func ( *Error) () string        { return .name }
func ( *Error) () string { return .description }

func ( *Error) ( []byte,  label.Label) []byte {
	return append(, .From().Error()...)
}

// Of returns a new Label with this key and the supplied value.
func ( *Error) ( error) label.Label { return label.OfValue(, ) }

// Get returns the label for the key of a label.Map.
func ( *Error) ( label.Map) error {
	if  := .Find(); .Valid() {
		return .From()
	}
	return nil
}

// From returns the value of a Label.
func ( *Error) ( label.Label) error {
	,  := .UnpackValue().(error)
	return 
}