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

     1  // Copyright (c) 2020-2021 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package micheline
     5  
     6  import (
     7  	"strconv"
     8  	"strings"
     9  	"unicode"
    10  )
    11  
    12  const (
    13  	PATH_SEPARATOR          = "."
    14  	DEFAULT                 = "default"
    15  	PRIM                    = "prim"
    16  	INT                     = "int"
    17  	BYTES                   = "bytes"
    18  	STRING                  = "string"
    19  	ROOT                    = "root"
    20  	ANNOTS                  = "annots"
    21  	ARGS                    = "args"
    22  	DO                      = "do"
    23  	SET_DELEGATE            = "set_delegate"
    24  	REMOVE_DELEGATE         = "remove_delegate"
    25  	DEPOSIT                 = "deposit"
    26  	STAKE                   = "stake"
    27  	UNSTAKE                 = "unstake"
    28  	FINALIZE_UNSTAKE        = "finalize_unstake"
    29  	SET_DELEGATE_PARAMETERS = "set_delegate_parameters"
    30  )
    31  
    32  func isASCII(s string) bool {
    33  	for i := 0; i < len(s); i++ {
    34  		if s[i] < 32 || s[i] > unicode.MaxASCII {
    35  			return false
    36  		}
    37  	}
    38  	return true
    39  }
    40  
    41  func isASCIIBytes(b []byte) bool {
    42  	return isASCII(string(b))
    43  }
    44  
    45  func isPackedBytes(b []byte) bool {
    46  	return len(b) > 1 && b[0] == 0x5 && b[1] <= 0x0A // first primitive is valid
    47  }
    48  
    49  func limit(s string, l int) string {
    50  	return s[:min(len(s), l)]
    51  }
    52  
    53  func min(x, y int) int {
    54  	if x < y {
    55  		return x
    56  	}
    57  	return y
    58  }
    59  
    60  func getPath(val interface{}, path string) (interface{}, bool) {
    61  	if val == nil {
    62  		return nil, false
    63  	}
    64  	if path == "" {
    65  		return val, true
    66  	}
    67  	frag := strings.Split(path, PATH_SEPARATOR)
    68  	next := val
    69  	for i, v := range frag {
    70  		switch t := next.(type) {
    71  		case map[string]interface{}:
    72  			var ok bool
    73  			next, ok = t[v]
    74  			if !ok {
    75  				return nil, false
    76  			}
    77  		case []interface{}:
    78  			idx, err := strconv.Atoi(v)
    79  			if err != nil || idx < 0 || len(t) < idx {
    80  				return nil, false
    81  			}
    82  			next = t[idx]
    83  		default:
    84  			return next, i == len(frag)-1
    85  		}
    86  	}
    87  	return next, true
    88  }
    89  
    90  func walkValueMap(name string, val interface{}, fn ValueWalkerFunc) error {
    91  	switch t := val.(type) {
    92  	case map[string]interface{}:
    93  		if len(name) > 0 {
    94  			name += "."
    95  		}
    96  		for n, v := range t {
    97  			child := name + n
    98  			if err := walkValueMap(child, v, fn); err != nil {
    99  				return err
   100  			}
   101  		}
   102  	case []interface{}:
   103  		if len(name) > 0 {
   104  			name += "."
   105  		}
   106  		for i, v := range t {
   107  			child := name + strconv.Itoa(i)
   108  			if err := walkValueMap(child, v, fn); err != nil {
   109  				return err
   110  			}
   111  		}
   112  	default:
   113  		return fn(name, val)
   114  	}
   115  	return nil
   116  }