func (e *Encoder) MustEncode(v interface{}) {
	halt.onerror(e.err)
	if e.hh == nil {
		halt.onerror(errNoFormatHandle)
	}
	e.calls++
	e.encode(v)
	e.calls--
	if e.calls == 0 {
		e.e.atEndOfEncode()
		e.w().end()
	}
}
MustEncode is like Encode, but panics if unable to Encode.

Note: This provides insight to the code location that triggered the error.
package codec
import (
	"encoding"
	"errors"
	"io"
	"reflect"
	"sort"
	"strconv"
	"time"
)
const defEncByteBufSize = 1 << 10  
var errEncoderNotInitialized = errors.New("Encoder not initialized")
type encDriver interface {
	EncodeNil()
	EncodeInt(i int64)
	EncodeUint(i uint64)
	EncodeBool(b bool)
	EncodeFloat32(f float32)
	EncodeFloat64(f float64)
	EncodeRawExt(re *RawExt)
	EncodeExt(v interface{}, xtag uint64, ext Ext)
	EncodeString(v string)
	EncodeStringBytesRaw(v []byte)
	EncodeTime(time.Time)
	WriteArrayStart(length int)
	WriteArrayEnd()
	WriteMapStart(length int)
	WriteMapEnd()
	reset()
	atEndOfEncode()
	encoder() *Encoder
}
type encDriverContainerTracker interface {
	WriteArrayElem()
	WriteMapElemKey()
	WriteMapElemValue()
}
type encDriverNoopContainerWriter struct{}
func (encDriverNoopContainerWriter) WriteArrayStart(length int) {}
func (encDriverNoopContainerWriter) WriteArrayEnd()             {}
func (encDriverNoopContainerWriter) WriteMapStart(length int)   {}
func (encDriverNoopContainerWriter) WriteMapEnd()               {}
func (encDriverNoopContainerWriter) atEndOfEncode()             {}
type EncodeOptions struct {
	WriterBufferSize int
	ChanRecvTimeout time.Duration
	StructToArray bool
	Canonical bool
	CheckCircularRef bool
	RecursiveEmptyCheck bool
	Raw bool
	StringToRaw bool
	OptimumSize bool
}
func (e *Encoder) rawExt(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeRawExt(rv2i(rv).(*RawExt))
}
func (e *Encoder) ext(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeExt(rv2i(rv), f.xfTag, f.xfFn)
}
func (e *Encoder) selferMarshal(f *codecFnInfo, rv reflect.Value) {
	rv2i(rv).(Selfer).CodecEncodeSelf(e)
}
func (e *Encoder) binaryMarshal(f *codecFnInfo, rv reflect.Value) {
	bs, fnerr := rv2i(rv).(encoding.BinaryMarshaler).MarshalBinary()
	e.marshalRaw(bs, fnerr)
}
func (e *Encoder) textMarshal(f *codecFnInfo, rv reflect.Value) {
	bs, fnerr := rv2i(rv).(encoding.TextMarshaler).MarshalText()
	e.marshalUtf8(bs, fnerr)
}
func (e *Encoder) jsonMarshal(f *codecFnInfo, rv reflect.Value) {
	bs, fnerr := rv2i(rv).(jsonMarshaler).MarshalJSON()
	e.marshalAsis(bs, fnerr)
}
func (e *Encoder) raw(f *codecFnInfo, rv reflect.Value) {
	e.rawBytes(rv2i(rv).(Raw))
}
func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeBool(rvGetBool(rv))
}
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeTime(rvGetTime(rv))
}
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeString(rvGetString(rv))
}
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeFloat64(rvGetFloat64(rv))
}
func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeFloat32(rvGetFloat32(rv))
}
func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeInt(int64(rvGetInt(rv)))
}
func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeInt(int64(rvGetInt8(rv)))
}
func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeInt(int64(rvGetInt16(rv)))
}
func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeInt(int64(rvGetInt32(rv)))
}
func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeInt(int64(rvGetInt64(rv)))
}
func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeUint(uint64(rvGetUint(rv)))
}
func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeUint(uint64(rvGetUint8(rv)))
}
func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeUint(uint64(rvGetUint16(rv)))
}
func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeUint(uint64(rvGetUint32(rv)))
}
func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeUint(uint64(rvGetUint64(rv)))
}
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
	e.e.EncodeUint(uint64(rvGetUintptr(rv)))
}
func (e *Encoder) kErr(f *codecFnInfo, rv reflect.Value) {
	e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv)
}
func chanToSlice(rv reflect.Value, rtslice reflect.Type, timeout time.Duration) (rvcs reflect.Value) {
	rvcs = rvZero(rtslice)
	if timeout < 0 {  
		for {
			recv, recvOk := rv.Recv()
			if !recvOk {
				break
			}
			rvcs = reflect.Append(rvcs, recv)
		}
	} else {
		cases := make([]reflect.SelectCase, 2)
		cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv}
		if timeout == 0 {
			cases[1] = reflect.SelectCase{Dir: reflect.SelectDefault}
		} else {
			tt := time.NewTimer(timeout)
			cases[1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: rv4i(tt.C)}
		}
		for {
			chosen, recv, recvOk := reflect.Select(cases)
			if chosen == 1 || !recvOk {
				break
			}
			rvcs = reflect.Append(rvcs, recv)
		}
	}
	return
}
func (e *Encoder) kSeqFn(rtelem reflect.Type) (fn *codecFn) {
	for rtelem.Kind() == reflect.Ptr {
		rtelem = rtelem.Elem()
	}
	if rtelem.Kind() != reflect.Interface {
		fn = e.h.fn(rtelem)
	}
	return
}
func (e *Encoder) kSliceWMbs(rv reflect.Value, ti *typeInfo) {
	var l = rvLenSlice(rv)
	if l == 0 {
		e.mapStart(0)
	} else {
		e.haltOnMbsOddLen(l)
		e.mapStart(l >> 1)  
		fn := e.kSeqFn(ti.elem)
		for j := 0; j < l; j++ {
			if j&1 == 0 {  
				e.mapElemKey()
			} else {
				e.mapElemValue()
			}
			e.encodeValue(rvSliceIndex(rv, j, ti), fn)
		}
	}
	e.mapEnd()
}
func (e *Encoder) kSliceW(rv reflect.Value, ti *typeInfo) {
	var l = rvLenSlice(rv)
	e.arrayStart(l)
	if l > 0 {
		fn := e.kSeqFn(ti.elem)
		for j := 0; j < l; j++ {
			e.arrayElem()
			e.encodeValue(rvSliceIndex(rv, j, ti), fn)
		}
	}
	e.arrayEnd()
}
func (e *Encoder) kArrayWMbs(rv reflect.Value, ti *typeInfo) {
	var l = rvLenArray(rv)
	if l == 0 {
		e.mapStart(0)
	} else {
		e.haltOnMbsOddLen(l)
		e.mapStart(l >> 1)  
		fn := e.kSeqFn(ti.elem)
		for j := 0; j < l; j++ {
			if j&1 == 0 {  
				e.mapElemKey()
			} else {
				e.mapElemValue()
			}
			e.encodeValue(rv.Index(j), fn)
		}
	}
	e.mapEnd()
}
func (e *Encoder) kArrayW(rv reflect.Value, ti *typeInfo) {
	var l = rvLenArray(rv)
	e.arrayStart(l)
	if l > 0 {
		fn := e.kSeqFn(ti.elem)
		for j := 0; j < l; j++ {
			e.arrayElem()
			e.encodeValue(rv.Index(j), fn)
		}
	}
	e.arrayEnd()
}
func (e *Encoder) kChan(f *codecFnInfo, rv reflect.Value) {
	if f.ti.chandir&uint8(reflect.RecvDir) == 0 {
		e.errorf("send-only channel cannot be encoded")
	}
	if !f.ti.mbs && uint8TypId == rt2id(f.ti.elem) {
		e.kSliceBytesChan(rv)
		return
	}
	rtslice := reflect.SliceOf(f.ti.elem)
	rv = chanToSlice(rv, rtslice, e.h.ChanRecvTimeout)
	ti := e.h.getTypeInfo(rt2id(rtslice), rtslice)
	if f.ti.mbs {
		e.kSliceWMbs(rv, ti)
	} else {
		e.kSliceW(rv, ti)
	}
}
func (e *Encoder) kSlice(f *codecFnInfo, rv reflect.Value) {
	if f.ti.mbs {
		e.kSliceWMbs(rv, f.ti)
	} else if f.ti.rtid == uint8SliceTypId || uint8TypId == rt2id(f.ti.elem) {
		e.e.EncodeStringBytesRaw(rvGetBytes(rv))
	} else {
		e.kSliceW(rv, f.ti)
	}
}
func (e *Encoder) kArray(f *codecFnInfo, rv reflect.Value) {
	if f.ti.mbs {
		e.kArrayWMbs(rv, f.ti)
	} else if uint8TypId == rt2id(f.ti.elem) {
		e.e.EncodeStringBytesRaw(rvGetArrayBytesRO(rv, e.b[:]))
	} else {
		e.kArrayW(rv, f.ti)
	}
}
func (e *Encoder) kSliceBytesChan(rv reflect.Value) {
	bs := e.b[:0]
	irv := rv2i(rv)
	ch, ok := irv.(<-chan byte)
	if !ok {
		ch = irv.(chan byte)
	}
L1:
	switch timeout := e.h.ChanRecvTimeout; {
	case timeout == 0:  
		for {
			select {
			case b := <-ch:
				bs = append(bs, b)
			default:
				break L1
			}
		}
	case timeout > 0:  
		tt := time.NewTimer(timeout)
		for {
			select {
			case b := <-ch:
				bs = append(bs, b)
			case <-tt.C:
				break L1
			}
		}
	default:  
		for b := range ch {
			bs = append(bs, b)
		}
	}
	e.e.EncodeStringBytesRaw(bs)
}
func (e *Encoder) kStructSfi(f *codecFnInfo) []*structFieldInfo {
	if e.h.Canonical {
		return f.ti.sfiSort
	}
	return f.ti.sfiSrc
}
func (e *Encoder) kStructNoOmitempty(f *codecFnInfo, rv reflect.Value) {
	if f.ti.toArray || e.h.StructToArray {  
		e.arrayStart(len(f.ti.sfiSrc))
		for _, si := range f.ti.sfiSrc {
			e.arrayElem()
			e.encodeValue(si.path.field(rv), nil)
		}
		e.arrayEnd()
	} else {
		tisfi := e.kStructSfi(f)
		e.mapStart(len(tisfi))
		for _, si := range tisfi {
			e.mapElemKey()
			e.kStructFieldKey(f.ti.keyType, si.path.encNameAsciiAlphaNum, si.encName)
			e.mapElemValue()
			e.encodeValue(si.path.field(rv), nil)
		}
		e.mapEnd()
	}
}
func (e *Encoder) kStructFieldKey(keyType valueType, encNameAsciiAlphaNum bool, encName string) {
	encStructFieldKey(encName, e.e, e.w(), keyType, encNameAsciiAlphaNum, e.js)
}
func (e *Encoder) kStruct(f *codecFnInfo, rv reflect.Value) {
	var newlen int
	toMap := !(f.ti.toArray || e.h.StructToArray)
	var mf map[string]interface{}
	if f.ti.flagMissingFielder {
		mf = rv2i(rv).(MissingFielder).CodecMissingFields()
		toMap = true
		newlen += len(mf)
	} else if f.ti.flagMissingFielderPtr {
		if rv.CanAddr() {
			mf = rv2i(rv.Addr()).(MissingFielder).CodecMissingFields()
		} else {
			rv2 := reflect.New(rvType(rv))
			rvSetDirect(rv2.Elem(), rv)
			mf = rv2i(rv2).(MissingFielder).CodecMissingFields()
		}
		toMap = true
		newlen += len(mf)
	}
	newlen += len(f.ti.sfiSrc)
	var fkvs = e.slist.get(newlen)[:newlen]
	recur := e.h.RecursiveEmptyCheck
	var kv sfiRv
	var j int
	if toMap {
		newlen = 0
		for _, si := range e.kStructSfi(f) {
			kv.r = si.path.field(rv)
			if si.path.omitEmpty && isEmptyValue(kv.r, e.h.TypeInfos, recur) {
				continue
			}
			kv.v = si
			fkvs[newlen] = kv
			newlen++
		}
		var mflen int
		for k, v := range mf {
			if k == "" {
				delete(mf, k)
				continue
			}
			if f.ti.infoFieldOmitempty && isEmptyValue(rv4i(v), e.h.TypeInfos, recur) {
				delete(mf, k)
				continue
			}
			mflen++
		}
		e.mapStart(newlen + mflen)
		for j = 0; j < newlen; j++ {
			kv = fkvs[j]
			e.mapElemKey()
			e.kStructFieldKey(f.ti.keyType, kv.v.path.encNameAsciiAlphaNum, kv.v.encName)
			e.mapElemValue()
			e.encodeValue(kv.r, nil)
		}
		for k, v := range mf {
			e.mapElemKey()
			e.kStructFieldKey(f.ti.keyType, false, k)
			e.mapElemValue()
			e.encode(v)
		}
		e.mapEnd()
	} else {
		newlen = len(f.ti.sfiSrc)
		for i, si := range f.ti.sfiSrc {  
			kv.r = si.path.field(rv)
			if si.path.omitEmpty && isEmptyValue(kv.r, e.h.TypeInfos, recur) {
				switch kv.r.Kind() {
				case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice:
					kv.r = reflect.Value{}  
				}
			}
			fkvs[i] = kv
		}
		e.arrayStart(newlen)
		for j = 0; j < newlen; j++ {
			e.arrayElem()
			e.encodeValue(fkvs[j].r, nil)
		}
		e.arrayEnd()
	}
	e.slist.put(fkvs)
}
func (e *Encoder) kMap(f *codecFnInfo, rv reflect.Value) {
	l := rvLenMap(rv)
	e.mapStart(l)
	if l == 0 {
		e.mapEnd()
		return
	}
	var keyFn, valFn *codecFn
	ktypeKind := f.ti.key.Kind()
	vtypeKind := f.ti.elem.Kind()
	rtval := f.ti.elem
	rtvalkind := vtypeKind
	for rtvalkind == reflect.Ptr {
		rtval = rtval.Elem()
		rtvalkind = rtval.Kind()
	}
	if rtvalkind != reflect.Interface {
		valFn = e.h.fn(rtval)
	}
	var rvv = mapAddrLoopvarRV(f.ti.elem, vtypeKind)
	if e.h.Canonical {
		e.kMapCanonical(f.ti.key, f.ti.elem, rv, rvv, valFn)
		e.mapEnd()
		return
	}
	rtkey := f.ti.key
	var keyTypeIsString = stringTypId == rt2id(rtkey)  
	if !keyTypeIsString {
		for rtkey.Kind() == reflect.Ptr {
			rtkey = rtkey.Elem()
		}
		if rtkey.Kind() != reflect.Interface {
			keyFn = e.h.fn(rtkey)
		}
	}
	var rvk = mapAddrLoopvarRV(f.ti.key, ktypeKind)
	var it mapIter
	mapRange(&it, rv, rvk, rvv, true)
	for it.Next() {
		e.mapElemKey()
		if keyTypeIsString {
			e.e.EncodeString(it.Key().String())
		} else {
			e.encodeValue(it.Key(), keyFn)
		}
		e.mapElemValue()
		e.encodeValue(it.Value(), valFn)
	}
	it.Done()
	e.mapEnd()
}
func (e *Encoder) kMapCanonical(rtkey, rtval reflect.Type, rv, rvv reflect.Value, valFn *codecFn) {
	mks := rv.MapKeys()
	switch rtkey.Kind() {
	case reflect.Bool:
		mksv := make([]boolRv, len(mks))
		for i, k := range mks {
			v := &mksv[i]
			v.r = k
			v.v = k.Bool()
		}
		sort.Sort(boolRvSlice(mksv))
		for i := range mksv {
			e.mapElemKey()
			e.e.EncodeBool(mksv[i].v)
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
		}
	case reflect.String:
		mksv := make([]stringRv, len(mks))
		for i, k := range mks {
			v := &mksv[i]
			v.r = k
			v.v = k.String()
		}
		sort.Sort(stringRvSlice(mksv))
		for i := range mksv {
			e.mapElemKey()
			e.e.EncodeString(mksv[i].v)
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
		}
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr:
		mksv := make([]uint64Rv, len(mks))
		for i, k := range mks {
			v := &mksv[i]
			v.r = k
			v.v = k.Uint()
		}
		sort.Sort(uint64RvSlice(mksv))
		for i := range mksv {
			e.mapElemKey()
			e.e.EncodeUint(mksv[i].v)
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
		}
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
		mksv := make([]int64Rv, len(mks))
		for i, k := range mks {
			v := &mksv[i]
			v.r = k
			v.v = k.Int()
		}
		sort.Sort(int64RvSlice(mksv))
		for i := range mksv {
			e.mapElemKey()
			e.e.EncodeInt(mksv[i].v)
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
		}
	case reflect.Float32:
		mksv := make([]float64Rv, len(mks))
		for i, k := range mks {
			v := &mksv[i]
			v.r = k
			v.v = k.Float()
		}
		sort.Sort(float64RvSlice(mksv))
		for i := range mksv {
			e.mapElemKey()
			e.e.EncodeFloat32(float32(mksv[i].v))
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
		}
	case reflect.Float64:
		mksv := make([]float64Rv, len(mks))
		for i, k := range mks {
			v := &mksv[i]
			v.r = k
			v.v = k.Float()
		}
		sort.Sort(float64RvSlice(mksv))
		for i := range mksv {
			e.mapElemKey()
			e.e.EncodeFloat64(mksv[i].v)
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
		}
	case reflect.Struct:
		if rtkey == timeTyp {
			mksv := make([]timeRv, len(mks))
			for i, k := range mks {
				v := &mksv[i]
				v.r = k
				v.v = rv2i(k).(time.Time)
			}
			sort.Sort(timeRvSlice(mksv))
			for i := range mksv {
				e.mapElemKey()
				e.e.EncodeTime(mksv[i].v)
				e.mapElemValue()
				e.encodeValue(mapGet(rv, mksv[i].r, rvv), valFn)
			}
			break
		}
		fallthrough
	default:
		var mksv = e.blist.get(len(mks) * 16)
		e2 := NewEncoderBytes(&mksv, e.hh)
		mksbv := make([]bytesRv, len(mks))
		for i, k := range mks {
			v := &mksbv[i]
			l := len(mksv)
			e2.MustEncode(k)
			v.r = k
			v.v = mksv[l:]
		}
		sort.Sort(bytesRvSlice(mksbv))
		for j := range mksbv {
			e.mapElemKey()
			e.encWr.writeb(mksbv[j].v)
			e.mapElemValue()
			e.encodeValue(mapGet(rv, mksbv[j].r, rvv), valFn)
		}
		e.blist.put(mksv)
	}
}
type Encoder struct {
	panicHdl
	e encDriver
	h *BasicHandle
	encWr
	hh Handle
	blist bytesFreelist
	err   error
	ci []interface{}  
	slist sfiRvFreelist
	b [2 * 8]byte  
}
func NewEncoder(w io.Writer, h Handle) *Encoder {
	e := h.newEncDriver().encoder()
	e.Reset(w)
	return e
}
func NewEncoderBytes(out *[]byte, h Handle) *Encoder {
	e := h.newEncDriver().encoder()
	e.ResetBytes(out)
	return e
}
func (e *Encoder) init(h Handle) {
	initHandle(h)
	e.err = errEncoderNotInitialized
	e.bytes = true
	e.hh = h
	e.h = h.getBasicHandle()
	e.be = e.hh.isBinary()
}
func (e *Encoder) w() *encWr {
	return &e.encWr
}
func (e *Encoder) resetCommon() {
	e.e.reset()
	if e.ci != nil {
		e.ci = e.ci[:0]
	}
	e.c = 0
	e.calls = 0
	e.err = nil
}
func (e *Encoder) Reset(w io.Writer) {
	if w == nil {
		return
	}
	e.bytes = false
	if e.wf == nil {
		e.wf = new(bufioEncWriter)
	}
	e.wf.reset(w, e.h.WriterBufferSize, &e.blist)
	e.resetCommon()
}
func (e *Encoder) ResetBytes(out *[]byte) {
	if out == nil {
		return
	}
	var in []byte = *out
	if in == nil {
		in = make([]byte, defEncByteBufSize)
	}
	e.bytes = true
	e.wb.reset(in, out)
	e.resetCommon()
}
func (e *Encoder) Encode(v interface{}) (err error) {
	defer func() {
		if x := recover(); x != nil {
			panicValToErr(e, x, &e.err)
			err = e.err
		}
	}()
	e.MustEncode(v)
	return
}