package chickpeas

import 

// ValueKind discriminates a Value.
type ValueKind uint8

const (
	// KindStr is an interned-string value (the payload is an atom id).
	KindStr ValueKind = iota
	// KindI64 is an integer value.
	KindI64
	// KindF64 is a float value, stored by bit pattern.
	KindF64
	// KindBool is a boolean value.
	KindBool
)

// Value is a property value: the Go port of the Rust ValueId tagged union.
// It is comparable -- usable as a map key with == -- with the same equality
// semantics as the Rust derive: strings compare by atom id and floats by
// IEEE-754 bit pattern (so NaN == NaN when the payloads match, and
// 0.0 != -0.0).
type Value struct {
	kind ValueKind
	bits uint64
}

// StrValue is an interned-string value holding an atom id.
func ( uint32) Value {
	return Value{kind: KindStr, bits: uint64()}
}

// I64Value is an integer value.
func ( int64) Value {
	return Value{kind: KindI64, bits: uint64()}
}

// F64Value is a float value, stored by bit pattern.
func ( float64) Value {
	return Value{kind: KindF64, bits: math.Float64bits()}
}

// BoolValue is a boolean value.
func ( bool) Value {
	var  uint64
	if  {
		 = 1
	}
	return Value{kind: KindBool, bits: }
}

// Kind reports the value's discriminant.
func ( Value) () ValueKind { return .kind }

// StrID returns the interned-string atom id; ok is false for other kinds.
func ( Value) () (uint32, bool) {
	return uint32(.bits), .kind == KindStr
}

// I64 returns the integer value; ok is false for other kinds.
func ( Value) () (int64, bool) {
	return int64(.bits), .kind == KindI64
}

// F64 returns the float value; ok is false for other kinds.
func ( Value) () (float64, bool) {
	return math.Float64frombits(.bits), .kind == KindF64
}

// Bool returns the boolean value; ok is false for other kinds.
func ( Value) () (bool, bool) {
	return .bits != 0, .kind == KindBool
}