encode.go
func (e Encoder) Encode(v interface{}) (err error) {
	if err = e.encodeMapValueMaybe(); err != nil {
		return
	}

	// This type switch optimizes encoding of common value types, it prevents
	// the use of reflection to identify the type of the value, which saves a
	// dynamic memory allocation.
	switch x := v.(type) {
	case nil:
		return e.Emitter.EmitNil()

	case bool:
		return e.Emitter.EmitBool(x)

	case int:
		return e.Emitter.EmitInt(int64(x), 0)

	case int8:
		return e.Emitter.EmitInt(int64(x), 8)

	case int16:
		return e.Emitter.EmitInt(int64(x), 16)

	case int32:
		return e.Emitter.EmitInt(int64(x), 32)

	case int64:
		return e.Emitter.EmitInt(x, 64)

	case uint8:
		return e.Emitter.EmitUint(uint64(x), 8)

	case uint16:
		return e.Emitter.EmitUint(uint64(x), 16)

	case uint32:
		return e.Emitter.EmitUint(uint64(x), 32)

	case uint64:
		return e.Emitter.EmitUint(x, 64)

	case string:
		return e.Emitter.EmitString(x)

	case []byte:
		return e.Emitter.EmitBytes(x)

	case time.Time:
		return e.Emitter.EmitTime(x)

	case time.Duration:
		return e.Emitter.EmitDuration(x)

	case []string:
		return e.encodeSliceOfString(x)

	case []interface{}:
		return e.encodeSliceOfInterface(x)

	case map[string]string:
		return e.encodeMapStringString(x)

	case map[string]interface{}:
		return e.encodeMapStringInterface(x)

	case map[interface{}]interface{}:
		return e.encodeMapInterfaceInterface(x)

		// Also checks for pointer types so the program can use this as a way
		// to avoid the dynamic memory allocation done by runtime.convT2E for
		// converting non-pointer types to empty interfaces.
	case *bool:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitBool(*x)

	case *int:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), int(8*unsafe.Sizeof(0)))

	case *int8:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), 8)

	case *int16:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), 16)

	case *int32:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), 32)

	case *int64:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(*x, 64)

	case *uint8:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(uint64(*x), 8)

	case *uint16:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(uint64(*x), 16)

	case *uint32:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(uint64(*x), 32)

	case *uint64:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(*x, 64)

	case *string:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitString(*x)

	case *[]byte:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitBytes(*x)

	case *time.Time:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitTime(*x)

	case *time.Duration:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitDuration(*x)

	case *[]string:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeSliceOfString(*x)

	case *[]interface{}:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeSliceOfInterface(*x)

	case *map[string]string:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeMapStringString(*x)

	case *map[string]interface{}:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeMapStringInterface(*x)

	case *map[interface{}]interface{}:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeMapInterfaceInterface(*x)

	case ValueEncoder:
		return x.EncodeValue(e)

	default:
		return e.encode(reflect.ValueOf(v))
	}
}
func (e Encoder) Encode(v interface{}) (err error) {
	if err = e.encodeMapValueMaybe(); err != nil {
		return
	}

	// This type switch optimizes encoding of common value types, it prevents
	// the use of reflection to identify the type of the value, which saves a
	// dynamic memory allocation.
	switch x := v.(type) {
	case nil:
		return e.Emitter.EmitNil()

	case bool:
		return e.Emitter.EmitBool(x)

	case int:
		return e.Emitter.EmitInt(int64(x), 0)

	case int8:
		return e.Emitter.EmitInt(int64(x), 8)

	case int16:
		return e.Emitter.EmitInt(int64(x), 16)

	case int32:
		return e.Emitter.EmitInt(int64(x), 32)

	case int64:
		return e.Emitter.EmitInt(x, 64)

	case uint8:
		return e.Emitter.EmitUint(uint64(x), 8)

	case uint16:
		return e.Emitter.EmitUint(uint64(x), 16)

	case uint32:
		return e.Emitter.EmitUint(uint64(x), 32)

	case uint64:
		return e.Emitter.EmitUint(x, 64)

	case string:
		return e.Emitter.EmitString(x)

	case []byte:
		return e.Emitter.EmitBytes(x)

	case time.Time:
		return e.Emitter.EmitTime(x)

	case time.Duration:
		return e.Emitter.EmitDuration(x)

	case []string:
		return e.encodeSliceOfString(x)

	case []interface{}:
		return e.encodeSliceOfInterface(x)

	case map[string]string:
		return e.encodeMapStringString(x)

	case map[string]interface{}:
		return e.encodeMapStringInterface(x)

	case map[interface{}]interface{}:
		return e.encodeMapInterfaceInterface(x)

		// Also checks for pointer types so the program can use this as a way
		// to avoid the dynamic memory allocation done by runtime.convT2E for
		// converting non-pointer types to empty interfaces.
	case *bool:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitBool(*x)

	case *int:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), int(8*unsafe.Sizeof(0)))

	case *int8:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), 8)

	case *int16:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), 16)

	case *int32:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(int64(*x), 32)

	case *int64:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitInt(*x, 64)

	case *uint8:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(uint64(*x), 8)

	case *uint16:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(uint64(*x), 16)

	case *uint32:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(uint64(*x), 32)

	case *uint64:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitUint(*x, 64)

	case *string:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitString(*x)

	case *[]byte:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitBytes(*x)

	case *time.Time:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitTime(*x)

	case *time.Duration:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.Emitter.EmitDuration(*x)

	case *[]string:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeSliceOfString(*x)

	case *[]interface{}:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeSliceOfInterface(*x)

	case *map[string]string:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeMapStringString(*x)

	case *map[string]interface{}:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeMapStringInterface(*x)

	case *map[interface{}]interface{}:
		if x == nil {
			return e.Emitter.EmitNil()
		}
		return e.encodeMapInterfaceInterface(*x)

	case ValueEncoder:
		return x.EncodeValue(e)

	default:
		return e.encode(reflect.ValueOf(v))
	}
}
// Encode encodes the generic value v.