PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/typeutil/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / typeutil
Files
3 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/typeutil/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • typeutil.gnogno
typeutil.gnogno
1// Package typeutil provides utility functions for converting between different types2// and checking their states. It aims to provide consistent behavior across different3// types while remaining lightweight and dependency-free.4package typeutil56import (7	"errors"8	"sort"9	"strconv"10	"strings"11	"time"12)1314// stringer is the interface that wraps the String method.15type stringer interface {16	String() string17}1819// ToString converts any value to its string representation.20// It supports a wide range of Go types including:21//   - Basic: string, bool22//   - Numbers: int, int8-64, uint, uint8-64, float32, float6423//   - Special: time.Time, address, []byte24//   - Slices: []T for most basic types25//   - Maps: map[string]string, map[string]any26//   - Interface: types implementing String() string27//28// Example usage:29//30//	str := typeutil.ToString(42)               // "42"31//	str = typeutil.ToString([]int{1, 2})      // "[1 2]"32//	str = typeutil.ToString(map[string]string{ // "map[a:1 b:2]"33//	    "a": "1",34//	    "b": "2",35//	})36func ToString(val any) string {37	if val == nil {38		return ""39	}4041	// First check if value implements Stringer interface42	if s, ok := val.(interface{ String() string }); ok {43		return s.String()44	}4546	switch v := val.(type) {47	// Pointer types - dereference and recurse48	case *string:49		if v == nil {50			return ""51		}52		return *v53	case *int:54		if v == nil {55			return ""56		}57		return strconv.Itoa(*v)58	case *bool:59		if v == nil {60			return ""61		}62		return strconv.FormatBool(*v)63	case *time.Time:64		if v == nil {65			return ""66		}67		return v.String()68	case *address:69		if v == nil {70			return ""71		}72		return string(*v)7374	// String types75	case string:76		return v77	case stringer:78		return v.String()7980	// Special types81	case time.Time:82		return v.String()83	case address:84		return string(v)85	case []byte:86		return string(v)87	case struct{}:88		return "{}"8990	// Integer types91	case int:92		return strconv.Itoa(v)93	case int8:94		return strconv.FormatInt(int64(v), 10)95	case int16:96		return strconv.FormatInt(int64(v), 10)97	case int32:98		return strconv.FormatInt(int64(v), 10)99	case int64:100		return strconv.FormatInt(v, 10)101	case uint:102		return strconv.FormatUint(uint64(v), 10)103	case uint8:104		return strconv.FormatUint(uint64(v), 10)105	case uint16:106		return strconv.FormatUint(uint64(v), 10)107	case uint32:108		return strconv.FormatUint(uint64(v), 10)109	case uint64:110		return strconv.FormatUint(v, 10)111112	// Float types113	case float32:114		return strconv.FormatFloat(float64(v), 'f', -1, 32)115	case float64:116		return strconv.FormatFloat(v, 'f', -1, 64)117118	// Boolean119	case bool:120		if v {121			return "true"122		}123		return "false"124125	// Slice types126	case []string:127		return join(v)128	case []int:129		return join(v)130	case []int32:131		return join(v)132	case []int64:133		return join(v)134	case []float32:135		return join(v)136	case []float64:137		return join(v)138	case []any:139		return join(v)140	case []time.Time:141		return joinTimes(v)142	case []stringer:143		return join(v)144	case []address:145		return joinAddresses(v)146	case [][]byte:147		return joinBytes(v)148149	// Map types with various key types150	case map[any]any, map[string]any, map[string]string, map[string]int:151		var b strings.Builder152		b.WriteString("map[")153		first := true154155		switch m := v.(type) {156		case map[any]any:157			// Convert all keys to strings for consistent ordering158			keys := make([]string, 0)159			keyMap := make(map[string]any)160161			for k := range m {162				keyStr := ToString(k)163				keys = append(keys, keyStr)164				keyMap[keyStr] = k165			}166			sort.Strings(keys)167168			for _, keyStr := range keys {169				if !first {170					b.WriteString(" ")171				}172				origKey := keyMap[keyStr]173				b.WriteString(keyStr)174				b.WriteString(":")175				b.WriteString(ToString(m[origKey]))176				first = false177			}178179		case map[string]any:180			keys := make([]string, 0)181			for k := range m {182				keys = append(keys, k)183			}184			sort.Strings(keys)185186			for _, k := range keys {187				if !first {188					b.WriteString(" ")189				}190				b.WriteString(k)191				b.WriteString(":")192				b.WriteString(ToString(m[k]))193				first = false194			}195196		case map[string]string:197			keys := make([]string, 0)198			for k := range m {199				keys = append(keys, k)200			}201			sort.Strings(keys)202203			for _, k := range keys {204				if !first {205					b.WriteString(" ")206				}207				b.WriteString(k)208				b.WriteString(":")209				b.WriteString(m[k])210				first = false211			}212213		case map[string]int:214			keys := make([]string, 0)215			for k := range m {216				keys = append(keys, k)217			}218			sort.Strings(keys)219220			for _, k := range keys {221				if !first {222					b.WriteString(" ")223				}224				b.WriteString(k)225				b.WriteString(":")226				b.WriteString(strconv.Itoa(m[k]))227				first = false228			}229		}230		b.WriteString("]")231		return b.String()232233	// Default234	default:235		return "<unknown>"236	}237}238239func join(slice any) string {240	if IsZero(slice) {241		return "[]"242	}243244	items := ToInterfaceSlice(slice)245	if items == nil {246		return "[]"247	}248249	var b strings.Builder250	b.WriteString("[")251	for i, item := range items {252		if i > 0 {253			b.WriteString(" ")254		}255		b.WriteString(ToString(item))256	}257	b.WriteString("]")258	return b.String()259}260261func joinTimes(slice []time.Time) string {262	if len(slice) == 0 {263		return "[]"264	}265	var b strings.Builder266	b.WriteString("[")267	for i, t := range slice {268		if i > 0 {269			b.WriteString(" ")270		}271		b.WriteString(t.String())272	}273	b.WriteString("]")274	return b.String()275}276277func joinAddresses(slice []address) string {278	if len(slice) == 0 {279		return "[]"280	}281	var b strings.Builder282	b.WriteString("[")283	for i, addr := range slice {284		if i > 0 {285			b.WriteString(" ")286		}287		b.WriteString(string(addr))288	}289	b.WriteString("]")290	return b.String()291}292293func joinBytes(slice [][]byte) string {294	if len(slice) == 0 {295		return "[]"296	}297	var b strings.Builder298	b.WriteString("[")299	for i, bytes := range slice {300		if i > 0 {301			b.WriteString(" ")302		}303		b.WriteString(string(bytes))304	}305	b.WriteString("]")306	return b.String()307}308309// ToBool converts any value to a boolean based on common programming conventions.310// For example:311//   - Numbers: 0 is false, any other number is true312//   - Strings: "", "0", "false", "f", "no", "n", "off" are false, others are true313//   - Slices/Maps: empty is false, non-empty is true314//   - nil: always false315//   - bool: direct value316func ToBool(val any) bool {317	if IsZero(val) {318		return false319	}320321	// Handle special string cases322	if str, ok := val.(string); ok {323		str = strings.ToLower(strings.TrimSpace(str))324		return str != "" && str != "0" && str != "false" && str != "f" && str != "no" && str != "n" && str != "off"325	}326327	return true328}329330// IsZero returns true if the value represents a "zero" or "empty" state for its type.331// For example:332//   - Numbers: 0333//   - Strings: ""334//   - Slices/Maps: empty335//   - nil: true336//   - bool: false337//   - time.Time: IsZero()338//   - address: empty string339func IsZero(val any) bool {340	if val == nil {341		return true342	}343344	switch v := val.(type) {345	// Pointer types - nil pointer is zero, otherwise check pointed value346	case *bool:347		return v == nil || !*v348	case *string:349		return v == nil || *v == ""350	case *int:351		return v == nil || *v == 0352	case *time.Time:353		return v == nil || v.IsZero()354	case *address:355		return v == nil || string(*v) == ""356357	// Bool358	case bool:359		return !v360361	// String types362	case string:363		return v == ""364	case stringer:365		return v.String() == ""366367	// Integer types368	case int:369		return v == 0370	case int8:371		return v == 0372	case int16:373		return v == 0374	case int32:375		return v == 0376	case int64:377		return v == 0378	case uint:379		return v == 0380	case uint8:381		return v == 0382	case uint16:383		return v == 0384	case uint32:385		return v == 0386	case uint64:387		return v == 0388389	// Float types390	case float32:391		return v == 0392	case float64:393		return v == 0394395	// Special types396	case []byte:397		return len(v) == 0398	case time.Time:399		return v.IsZero()400	case address:401		return string(v) == ""402403	// Slices (check if empty)404	case []string:405		return len(v) == 0406	case []int:407		return len(v) == 0408	case []int32:409		return len(v) == 0410	case []int64:411		return len(v) == 0412	case []float32:413		return len(v) == 0414	case []float64:415		return len(v) == 0416	case []any:417		return len(v) == 0418	case []time.Time:419		return len(v) == 0420	case []address:421		return len(v) == 0422	case [][]byte:423		return len(v) == 0424	case []stringer:425		return len(v) == 0426427	// Maps (check if empty)428	case map[string]string:429		return len(v) == 0430	case map[string]any:431		return len(v) == 0432433	default:434		return false // non-nil unknown types are considered non-zero435	}436}437438// ToInterfaceSlice converts various slice types to []any439func ToInterfaceSlice(val any) []any {440	switch v := val.(type) {441	case []any:442		return v443	case []string:444		result := make([]any, len(v))445		for i, s := range v {446			result[i] = s447		}448		return result449	case []int:450		result := make([]any, len(v))451		for i, n := range v {452			result[i] = n453		}454		return result455	case []int32:456		result := make([]any, len(v))457		for i, n := range v {458			result[i] = n459		}460		return result461	case []int64:462		result := make([]any, len(v))463		for i, n := range v {464			result[i] = n465		}466		return result467	case []float32:468		result := make([]any, len(v))469		for i, n := range v {470			result[i] = n471		}472		return result473	case []float64:474		result := make([]any, len(v))475		for i, n := range v {476			result[i] = n477		}478		return result479	case []bool:480		result := make([]any, len(v))481		for i, b := range v {482			result[i] = b483		}484		return result485	default:486		return nil487	}488}489490// ToMapStringInterface converts a map with string keys and any value type to map[string]any491func ToMapStringInterface(m any) (map[string]any, error) {492	result := make(map[string]any)493494	switch v := m.(type) {495	case map[string]any:496		return v, nil497	case map[string]string:498		for k, val := range v {499			result[k] = val500		}501	case map[string]int:502		for k, val := range v {503			result[k] = val504		}505	case map[string]int64:506		for k, val := range v {507			result[k] = val508		}509	case map[string]float64:510		for k, val := range v {511			result[k] = val512		}513	case map[string]bool:514		for k, val := range v {515			result[k] = val516		}517	case map[string][]string:518		for k, val := range v {519			result[k] = ToInterfaceSlice(val)520		}521	case map[string][]int:522		for k, val := range v {523			result[k] = ToInterfaceSlice(val)524		}525	case map[string][]any:526		for k, val := range v {527			result[k] = val528		}529	case map[string]map[string]any:530		for k, val := range v {531			result[k] = val532		}533	case map[string]map[string]string:534		for k, val := range v {535			if converted, err := ToMapStringInterface(val); err == nil {536				result[k] = converted537			} else {538				return nil, errors.New("failed to convert nested map at key: " + k)539			}540		}541	default:542		return nil, errors.New("unsupported map type: " + ToString(m))543	}544545	return result, nil546}547548// ToMapIntInterface converts a map with int keys and any value type to map[int]any549func ToMapIntInterface(m any) (map[int]any, error) {550	result := make(map[int]any)551552	switch v := m.(type) {553	case map[int]any:554		return v, nil555	case map[int]string:556		for k, val := range v {557			result[k] = val558		}559	case map[int]int:560		for k, val := range v {561			result[k] = val562		}563	case map[int]int64:564		for k, val := range v {565			result[k] = val566		}567	case map[int]float64:568		for k, val := range v {569			result[k] = val570		}571	case map[int]bool:572		for k, val := range v {573			result[k] = val574		}575	case map[int][]string:576		for k, val := range v {577			result[k] = ToInterfaceSlice(val)578		}579	case map[int][]int:580		for k, val := range v {581			result[k] = ToInterfaceSlice(val)582		}583	case map[int][]any:584		for k, val := range v {585			result[k] = val586		}587	case map[int]map[string]any:588		for k, val := range v {589			result[k] = val590		}591	case map[int]map[int]any:592		for k, val := range v {593			result[k] = val594		}595	default:596		return nil, errors.New("unsupported map type: " + ToString(m))597	}598599	return result, nil600}601602// ToStringSlice converts various slice types to []string603func ToStringSlice(val any) []string {604	switch v := val.(type) {605	case []string:606		return v607	case []any:608		result := make([]string, len(v))609		for i, item := range v {610			result[i] = ToString(item)611		}612		return result613	case []int:614		result := make([]string, len(v))615		for i, n := range v {616			result[i] = strconv.Itoa(n)617		}618		return result619	case []int32:620		result := make([]string, len(v))621		for i, n := range v {622			result[i] = strconv.FormatInt(int64(n), 10)623		}624		return result625	case []int64:626		result := make([]string, len(v))627		for i, n := range v {628			result[i] = strconv.FormatInt(n, 10)629		}630		return result631	case []float32:632		result := make([]string, len(v))633		for i, n := range v {634			result[i] = strconv.FormatFloat(float64(n), 'f', -1, 32)635		}636		return result637	case []float64:638		result := make([]string, len(v))639		for i, n := range v {640			result[i] = strconv.FormatFloat(n, 'f', -1, 64)641		}642		return result643	case []bool:644		result := make([]string, len(v))645		for i, b := range v {646			result[i] = strconv.FormatBool(b)647		}648		return result649	case []time.Time:650		result := make([]string, len(v))651		for i, t := range v {652			result[i] = t.String()653		}654		return result655	case []address:656		result := make([]string, len(v))657		for i, addr := range v {658			result[i] = string(addr)659		}660		return result661	case [][]byte:662		result := make([]string, len(v))663		for i, b := range v {664			result[i] = string(b)665		}666		return result667	case []stringer:668		result := make([]string, len(v))669		for i, s := range v {670			result[i] = s.String()671		}672		return result673	case []uint:674		result := make([]string, len(v))675		for i, n := range v {676			result[i] = strconv.FormatUint(uint64(n), 10)677		}678		return result679	case []uint8:680		result := make([]string, len(v))681		for i, n := range v {682			result[i] = strconv.FormatUint(uint64(n), 10)683		}684		return result685	case []uint16:686		result := make([]string, len(v))687		for i, n := range v {688			result[i] = strconv.FormatUint(uint64(n), 10)689		}690		return result691	case []uint32:692		result := make([]string, len(v))693		for i, n := range v {694			result[i] = strconv.FormatUint(uint64(n), 10)695		}696		return result697	case []uint64:698		result := make([]string, len(v))699		for i, n := range v {700			result[i] = strconv.FormatUint(n, 10)701		}702		return result703	default:704		// Try to convert using reflection if it's a slice705		if slice := ToInterfaceSlice(val); slice != nil {706			result := make([]string, len(slice))707			for i, item := range slice {708				result[i] = ToString(item)709			}710			return result711		}712		return nil713	}714}715

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.