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  }