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 }