func TermToString(t Term) (s string, ok bool) {
	ok = true
	switch x := t.(type) {
	case Atom:
		s = string(x)
	case string:
		s = x
	case []byte:
		s = string(x)
	case List:
		str, err := convertCharlistToString(x)
		if err != nil {
			ok = false
			return
		}
		s = str
	default:
		ok = false
	}
	return
}
TermToString transforms given term (Atom, []byte, List) to the string
package etf
import (
	"fmt"
	"hash/fnv"
	"reflect"
	"strings"
)
type Term interface{}
type Tuple []Term
type List []Term
type Alias Ref
type ListImproper []Term
type Atom string
type Map map[Term]Term
type String string
type Charlist string
type Pid struct {
	Node     Atom
	ID       uint64
	Creation uint32
}
type Port struct {
	Node     Atom
	ID       uint32
	Creation uint32
}
type Ref struct {
	Node     Atom
	Creation uint32
	ID       [5]uint32
}
type Marshaler interface {
	MarshalETF() ([]byte, error)
}
type Unmarshaler interface {
	UnmarshalETF([]byte) error
}
type Function struct {
	Arity  byte
	Unique [16]byte
	Index  uint32
	Module    Atom
	OldIndex  uint32
	OldUnique uint32
	Pid       Pid
	FreeVars  []Term
}
var (
	hasher32 = fnv.New32a()
)
type Export struct {
	Module   Atom
	Function Atom
	Arity    int
}
const (
	ettAtom          = byte(100)  
	ettAtomUTF8      = byte(118)
	ettSmallAtom     = byte(115)  
	ettSmallAtomUTF8 = byte(119)
	ettString        = byte(107)
	ettCacheRef = byte(82)
	ettNewFloat = byte(70)
	ettSmallInteger = byte(97)
	ettInteger      = byte(98)
	ettLargeBig     = byte(111)
	ettSmallBig     = byte(110)
	ettList         = byte(108)
	ettListImproper = byte(18)  
	ettSmallTuple   = byte(104)
	ettLargeTuple   = byte(105)
	ettMap = byte(116)
	ettBinary    = byte(109)
	ettBitBinary = byte(77)
	ettNil = byte(106)
	ettPid      = byte(103)
	ettNewPid   = byte(88)  
	ettNewRef   = byte(114)
	ettNewerRef = byte(90)  
	ettExport = byte(113)
	ettFun    = byte(117)  
	ettNewFun = byte(112)
	ettPort    = byte(102)
	ettNewPort = byte(89)  
	ettFloat = byte(99)  
)
func (m Map) Element(k Term) Term {
	return m[k]
}
func (l List) Element(i int) Term {
	return l[i-1]
}
func (t Tuple) Element(i int) Term {
	return t[i-1]
}
func (p Pid) String() string {
	empty := Pid{}
	if p == empty {
		return "<0.0.0>"
	}
	n := uint32(0)
	if p.Node != "" {
		hasher32.Write([]byte(p.Node))
		defer hasher32.Reset()
		n = hasher32.Sum32()
	}
	return fmt.Sprintf("<%X.%d.%d>", n, int32(p.ID>>32), int32(p.ID))
}
func (r Ref) String() string {
	n := uint32(0)
	if r.Node != "" {
		hasher32.Write([]byte(r.Node))
		defer hasher32.Reset()
		n = hasher32.Sum32()
	}
	return fmt.Sprintf("Ref#<%X.%d.%d.%d>", n, r.ID[0], r.ID[1], r.ID[2])
}
func (a Alias) String() string {
	n := uint32(0)
	if a.Node != "" {
		hasher32.Write([]byte(a.Node))
		defer hasher32.Reset()
		n = hasher32.Sum32()
	}
	return fmt.Sprintf("Ref#<%X.%d.%d.%d>", n, a.ID[0], a.ID[1], a.ID[2])
}
type ProplistElement struct {
	Name  Atom
	Value Term
}