github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/utils/utils.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package utils 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 "log" 12 "net/http" 13 "os/exec" 14 "reflect" 15 "runtime" 16 "strconv" 17 "strings" 18 ) 19 20 // IsServerWriter tries to cast `w` into `http.ResponseWriter` 21 // and returns true if the cast was successful 22 func IsServerWriter(w io.Writer) bool { 23 _, ok := w.(http.ResponseWriter) 24 return ok 25 } 26 27 func OpenBrowser(url string) { 28 var err error 29 switch runtime.GOOS { 30 case "linux": 31 err = exec.Command("xdg-open", url).Start() 32 case "windows": 33 err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() 34 case "darwin": 35 err = exec.Command("open", url).Start() 36 default: 37 err = fmt.Errorf("unsupported platform") 38 } 39 if err != nil { 40 log.Fatal(err) 41 } 42 } 43 44 func PadNum(n int, totalLen int) string { 45 return PadLeft(strconv.Itoa(n), totalLen, '0') 46 } 47 48 func PadLeft(str string, totalLen int, pad rune) string { 49 if len(str) >= totalLen { 50 return str 51 } 52 if pad == 0 { 53 pad = ' ' 54 } 55 lead := "" 56 for i := 0; i < totalLen-len(str); i++ { 57 lead += string(pad) 58 } 59 return lead + str 60 } 61 62 func PadRight(str string, totalLen int, pad rune) string { 63 if len(str) >= totalLen { 64 return str 65 } 66 if pad == 0 { 67 pad = ' ' 68 } 69 tail := "" 70 for i := 0; i < totalLen-len(str); i++ { 71 tail += string(pad) 72 } 73 return str + tail 74 } 75 76 func MakeFirstLowerCase(s string) string { 77 if len(s) < 2 { 78 return strings.ToLower(s) 79 } 80 bts := []byte(s) 81 lc := bytes.ToLower([]byte{bts[0]}) 82 rest := bts[1:] 83 return string(bytes.Join([][]byte{lc, rest}, nil)) 84 } 85 86 func MakeFirstUpperCase(s string) string { 87 if len(s) < 2 { 88 return strings.ToLower(s) 89 } 90 bts := []byte(s) 91 lc := bytes.ToUpper([]byte{bts[0]}) 92 rest := bts[1:] 93 return string(bytes.Join([][]byte{lc, rest}, nil)) 94 } 95 96 // EarliestEvmTs - The timestamp of the first Ethereum block in summer 2015 was this value. Since Ethereum 97 // was the first EVM based blockchain, all other EVM based block chains have timestamps after this. We can 98 // use this fact to distinguish between block numbers and timestamps on the command line (any number in a block 99 // range smaller than this is a blockNumber, anything larger than this is a timestamp). This breaks when the 100 // block number gets larger than 1,4 billion, which may happen when the chain shards, but not until then. 101 const EarliestEvmTs = 1438269971 102 103 func GetFields(t *reflect.Type, format string, header bool) (fields []string, sep string, quote string) { 104 sep = "\t" 105 quote = "" 106 if format == "csv" || strings.Contains(format, ",") { 107 sep = "," 108 } 109 110 if format == "csv" || strings.Contains(format, "\"") { 111 quote = "\"" 112 } 113 114 if strings.Contains(format, "\t") || strings.Contains(format, ",") { 115 custom := strings.Replace(format, "\t", ",", -1) 116 custom = strings.Replace(custom, "\"", ",", -1) 117 fields = strings.Split(custom, ",") 118 119 } else { 120 realType := *t 121 122 if realType.Kind() == reflect.Pointer { 123 realType = realType.Elem() 124 } 125 126 if realType.Kind() != reflect.Struct { 127 log.Fatal(realType.Name() + " is not a structure") 128 } 129 for i := 0; i < realType.NumField(); i++ { 130 field := realType.Field(i) 131 // We don't want to return private fields 132 if !field.IsExported() { 133 continue 134 } 135 136 fn := field.Name 137 if header { 138 fields = append(fields, MakeFirstLowerCase(fn)) 139 } else { 140 fields = append(fields, fn) 141 } 142 } 143 } 144 145 return fields, sep, quote 146 } 147 148 func PointerOf[T any](value T) *T { 149 return &value 150 } 151 152 func LowerIfHex(addr string) string { 153 if !strings.HasPrefix(addr, "0x") { 154 return addr 155 } 156 return strings.ToLower(addr) 157 } 158 159 func StripComments(cmd string) string { 160 cmd = strings.Trim(strings.Replace(cmd, "\t", " ", -1), " \t") 161 if strings.Contains(cmd, "#") { 162 cmd = cmd[:strings.Index(cmd, "#")] 163 } 164 return cmd 165 }