github.com/aeternity/aepp-sdk-go/v6@v6.0.0/cmd/terminal.go (about)

     1  package cmd
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/big"
     7  	"reflect"
     8  
     9  	"time"
    10  
    11  	"github.com/aeternity/aepp-sdk-go/v6/config"
    12  	"github.com/aeternity/aepp-sdk-go/v6/naet"
    13  )
    14  
    15  func times(str string, n int) (out string) {
    16  	for i := 0; i < n; i++ {
    17  		out += str
    18  	}
    19  	return
    20  }
    21  
    22  var (
    23  	defaultIndentSize = 50
    24  )
    25  
    26  // Left left-pads the string with pad up to len runes
    27  // len may be exceeded if
    28  func left(str string, length int, pad string) string {
    29  	return times(pad, length-len(str)) + str
    30  }
    31  
    32  // Right right-pads the string with pad up to len runes
    33  func right(str string, length int, pad string) string {
    34  	return str + times(pad, length-len(str))
    35  }
    36  
    37  // Pp pretty print
    38  func Pp(data ...interface{}) {
    39  	PpI(0, data...)
    40  }
    41  
    42  // PpI pretty print indent
    43  func PpI(indentSize int, data ...interface{}) {
    44  	for i := 0; i < len(data); i += 2 {
    45  		rp := defaultIndentSize - indentSize
    46  
    47  		fmt.Printf("%v%v %v\n",
    48  			times("  ", indentSize),
    49  			right(fmt.Sprintf("%v", data[i]), rp, "_"),
    50  			data[i+1],
    51  		)
    52  	}
    53  }
    54  
    55  // PpT pretty print indent Title
    56  func PpT(indentSize int, title string) {
    57  	fmt.Printf("%v%v\n", times("  ", indentSize), title)
    58  }
    59  
    60  func printIf(title string, v interface{}) {
    61  	var p func(title, n string, v reflect.Value, dept int)
    62  	p = func(title, n string, v reflect.Value, dept int) {
    63  		switch v.Kind() {
    64  		// If it is a pointer we need to unwrap and call once again
    65  		case reflect.Ptr:
    66  			if v.IsValid() {
    67  				p(title, n, v.Elem(), dept)
    68  			}
    69  		case reflect.Interface:
    70  			p(title, n, v.Elem(), dept)
    71  		case reflect.Struct:
    72  			if v.Type().Name() == "Int" {
    73  				vc := v.Interface().(big.Int)
    74  				PpI(dept, "Balance", vc.Text(10))
    75  			} else {
    76  				PpT(dept, fmt.Sprintf("<%s>", v.Type().Name()))
    77  				dept++
    78  				for i := 0; i < v.NumField(); i++ {
    79  					p("", v.Type().Field(i).Name, v.Field(i), dept)
    80  				}
    81  				dept--
    82  				PpT(dept, fmt.Sprintf("</%s>", v.Type().Name()))
    83  			}
    84  		case reflect.Slice:
    85  			for i := 0; i < v.Len(); i++ {
    86  				p("", "", v.Index(i), dept)
    87  			}
    88  		default:
    89  			if len(n) > 0 {
    90  				if n == "Time" {
    91  					t := v.Uint() * uint64(time.Millisecond)
    92  					PpI(dept, n, time.Unix(0, int64(t)).Format(time.RFC3339))
    93  				} else {
    94  					PpI(dept, n, v)
    95  				}
    96  			}
    97  		}
    98  	}
    99  	p(title, "", reflect.ValueOf(v), 0)
   100  }
   101  
   102  // PrintObject pretty print an object obtained from the api with a title
   103  func PrintObject(title string, i interface{}) {
   104  	if config.Tuning.OutputFormatJSON {
   105  		j, _ := json.MarshalIndent(i, "", "  ")
   106  		fmt.Printf("%s\n", j)
   107  		return
   108  	}
   109  
   110  	printIf(title, i)
   111  	print("\n")
   112  
   113  }
   114  
   115  type getGenerationMicroBlockTransactioner interface {
   116  	naet.GetTransactionByHasher
   117  	naet.GetMicroBlockTransactionsByHasher
   118  	naet.GetGenerationByHeighter
   119  }
   120  
   121  // PrintGenerationByHeight utility function to print a generation by it's height
   122  // TODO needs to be tested with error cases
   123  func PrintGenerationByHeight(c getGenerationMicroBlockTransactioner, height uint64) {
   124  	r, err := c.GetGenerationByHeight(height)
   125  	if err == nil {
   126  		PrintObject("generation", r)
   127  		// search for transaction in the microblocks
   128  		for _, mbh := range r.MicroBlocks {
   129  			// get the microblok
   130  			mbhs := fmt.Sprint(mbh)
   131  			r, err := c.GetMicroBlockTransactionsByHash(mbhs)
   132  			if err != nil {
   133  				Pp("Error:", err)
   134  			}
   135  			// go through all the hashes
   136  			for _, btx := range r.Transactions {
   137  				p, err := c.GetTransactionByHash(fmt.Sprint(*btx.Hash))
   138  				if err == nil {
   139  					PrintObject("transaction", p)
   140  				} else {
   141  					fmt.Println("Error in c.GetTransactionByHash", err, btx.Hash)
   142  					continue
   143  				}
   144  			}
   145  		}
   146  	} else {
   147  		fmt.Println("Something went wrong in PrintGenerationByHeight")
   148  	}
   149  }