github.com/mavryk-network/mvgo@v1.19.9/micheline/debug.go (about)

     1  // Copyright (c) 2020-2021 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package micheline
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"io"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  func (p Prim) Dump() string {
    15  	buf, _ := p.MarshalJSON()
    16  	return string(buf)
    17  }
    18  
    19  func (p Prim) DumpLimit(n int) string {
    20  	buf, _ := p.MarshalJSON()
    21  	return limit(string(buf), n)
    22  }
    23  
    24  func (e Value) Dump() string {
    25  	buf := bytes.NewBuffer(nil)
    26  	e.DumpTo(buf)
    27  	return buf.String()
    28  }
    29  
    30  func (e Value) DumpLimit(n int) string {
    31  	return limit(e.Dump(), n)
    32  }
    33  
    34  func (e Value) DumpTo(w io.Writer) {
    35  	dumpTree(w, "", e.Type, e.Value)
    36  }
    37  
    38  func (s Stack) Dump() string {
    39  	return s.DumpIdent(0)
    40  }
    41  
    42  func (s Stack) DumpIdent(indent int) string {
    43  	idnt := strings.Repeat(" ", indent)
    44  	lines := make([]string, s.Len())
    45  	for i := range s {
    46  		n := len(s) - i - 1
    47  		lines[n] = idnt + fmt.Sprintf("%02d  ", n+1) + s[i].Dump()
    48  	}
    49  	return strings.Join(lines, "\n")
    50  }
    51  
    52  // TODO: improve tree output
    53  func dumpTree(w io.Writer, path string, typ Type, val Prim) {
    54  	if s, err := dump(path, typ, val); err != nil {
    55  		io.WriteString(w, err.Error())
    56  	} else {
    57  		io.WriteString(w, s)
    58  	}
    59  	switch val.Type {
    60  	case PrimSequence:
    61  		// keep the type
    62  		for i, v := range val.Args {
    63  			p := path + "." + strconv.Itoa(i)
    64  			dumpTree(w, p, typ, v)
    65  		}
    66  	default:
    67  		// advance type as well
    68  		for i, v := range val.Args {
    69  			t := Type{}
    70  			if len(typ.Args) > i {
    71  				t = Type{typ.Args[i]}
    72  			}
    73  			p := path + "." + strconv.Itoa(i)
    74  			dumpTree(w, p, t, v)
    75  		}
    76  	}
    77  }
    78  
    79  func dump(path string, typ Type, val Prim) (string, error) {
    80  	if !val.matchOpCode(typ.OpCode) {
    81  		return "", fmt.Errorf("Type mismatch val_type=%s type_code=%s", val.Type, typ.OpCode)
    82  	}
    83  
    84  	vtyp := "-"
    85  	switch val.Type {
    86  	case PrimSequence, PrimBytes, PrimInt, PrimString:
    87  	default:
    88  		vtyp = val.OpCode.String()
    89  	}
    90  
    91  	return fmt.Sprintf("path=%-20s val_prim=%-8s val_type=%-8s val_val=%-10s type_prim=%-8s type_code=%-8s type_name=%-8s\n",
    92  		path, val.Type, vtyp, val.DumpLimit(512), typ.Type, typ.OpCode, typ.Label(),
    93  	), nil
    94  }