func DefaultBuilder() Builder {
	return defaultBuilder
}
DefaultBuilder returns a builder with no constraints or checks.
package literal
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math"
	"strconv"
	"strings"
	"github.com/pborman/uuid"
)
type Type uint8
const (
	Bool Type = iota
	Int64
	Float64
	Text
	Blob
)
func (t Type) String() string {
	switch t {
	case Bool:
		return "bool"
	case Int64:
		return "int64"
	case Float64:
		return "float64"
	case Text:
		return "text"
	case Blob:
		return "blob"
	default:
		return "UNKNOWN"
	}
}
type Literal struct {
	t Type
	v interface{}
}
func (l *Literal) Type() Type {
	return l.t
}
func (l *Literal) String() string {
	return fmt.Sprintf("\"%v\"^^type:%v", l.Interface(), l.Type())
}
func (l *Literal) ToComparableString() string {
	s := ""
	switch l.t {
	case Int64:
		s = fmt.Sprintf("\"%032d\"^^type:%v", l.Interface(), l.Type())
	case Float64:
		s = fmt.Sprintf("\"%032f\"^^type:%v", l.Interface(), l.Type())
	default:
		s = l.String()
	}
	return s
}
func (l *Literal) Bool() (bool, error) {
	if l.t != Bool {
		return false, fmt.Errorf("literal.Bool: literal is of type %v; cannot be converted to a bool", l.t)
	}
	return l.v.(bool), nil
}
func (l *Literal) Int64() (int64, error) {
	if l.t != Int64 {
		return 0, fmt.Errorf("literal.Int64: literal is of type %v; cannot be converted to a int64", l.t)
	}
	return l.v.(int64), nil
}
func (l *Literal) Float64() (float64, error) {
	if l.t != Float64 {
		return 0, fmt.Errorf("literal.Float64: literal is of type %v; cannot be converted to a float64", l.t)
	}
	return l.v.(float64), nil
}
func (l *Literal) Text() (string, error) {
	if l.t != Text {
		return "", fmt.Errorf("literal.Text: literal is of type %v; cannot be converted to a string", l.t)
	}
	return l.v.(string), nil
}
func (l *Literal) Blob() ([]byte, error) {
	if l.t != Blob {
		return nil, fmt.Errorf("literal.Blob: literal is of type %v; cannot be converted to a []byte", l.t)
	}
	return l.v.([]byte), nil
}
func (l *Literal) Interface() interface{} {
	return l.v
}
type Builder interface {
	Build(t Type, v interface{}) (*Literal, error)
	Parse(s string) (*Literal, error)
}
var defaultBuilder Builder
func init() {
	defaultBuilder = &unboundBuilder{}
}
type unboundBuilder struct{}
func (b *unboundBuilder) Build(t Type, v interface{}) (*Literal, error) {
	switch v.(type) {
	case bool:
		if t != Bool {
			return nil, fmt.Errorf("literal.Build: type %v does not match type of value %v", t, v)
		}
	case int64:
		if t != Int64 {
			return nil, fmt.Errorf("literal.Build: type %v does not match type of value %v", t, v)
		}
	case float64:
		if t != Float64 {
			return nil, fmt.Errorf("literal.Build: type %v does not match type of value %v", t, v)
		}
	case string:
		if t != Text {
			return nil, fmt.Errorf("literal.Build: type %v does not match type of value %v", t, v)
		}
	case []byte:
		if t != Blob {
			return nil, fmt.Errorf("literal.Build: type %v does not match type of value %v", t, v)
		}
	default:
		return nil, fmt.Errorf("literal.Build: type %T is not supported when building literals", v)
	}
	return &Literal{
		t: t,
		v: v,
	}, nil
}
func (b *unboundBuilder) Parse(s string) (*Literal, error) {
	raw := strings.TrimSpace(s)
	if len(raw) == 0 {
		return nil, fmt.Errorf("literal.Parse: cannot parse and empty string into a literal; provided string %q", s)
	}
	if raw[0] != '"' {
		return nil, fmt.Errorf("literal.Parse: text encoded literals must start with \", missing in %s", raw)
	}
	idx := strings.Index(raw, "\"^^type:")
	if idx < 0 {
		return nil, fmt.Errorf("literal.Parse: text encoded literals must have a type; missing in %s", raw)
	}
	v := raw[1:idx]
	t := raw[idx+len("\"^^type:"):]
	switch t {
	case "bool":
		pv, err := strconv.ParseBool(v)
		if err != nil {
			return nil, fmt.Errorf("literal.Parse: could not convert value %q to bool", v)
		}
		return b.Build(Bool, pv)
	case "int64":
		pv, err := strconv.ParseInt(v, 10, 64)
		if err != nil {
			return nil, fmt.Errorf("literal.Parse: could not convert value %q to int64", v)
		}
		return b.Build(Int64, int64(pv))
	case "float64":
		pv, err := strconv.ParseFloat(v, 64)
		if err != nil {
			return nil, fmt.Errorf("literal.Parse: could not convert value %q to float64", v)
		}
		return b.Build(Float64, float64(pv))
	case "text":
		return b.Build(Text, v)
	case "blob":
		values := v[1 : len(v)-1]
		if values == "" {
			return b.Build(Blob, []byte{})
		}
		bs := []byte{}
		for _, s := range strings.Split(values, " ") {
			b, err := strconv.ParseUint(s, 10, 8)
			if err != nil {
				return nil, fmt.Errorf("literal.Parse: failed to decode byte array on %q with error %v", s, err)
			}
			bs = append(bs, byte(b))
		}
		return b.Build(Blob, bs)
	default:
		return nil, nil
	}
}