Parser.go

package util

import (
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"math/big"
	"net/url"
	"strings"
)

// Parser provides utility functions for various data manipulations.
type Parser struct{}

// DecBin converts a decimal integer to its binary representation with a specified length.
func DecBin(dec int, length int) []byte {
	switch length {
	case 1:
		return []byte{byte(dec)}
	case 2:
		b := make([]byte, 2)
		binary.BigEndian.PutUint16(b, uint16(dec))
		return b
	case 3, 4:
		b := make([]byte, 4)
		binary.BigEndian.PutUint32(b, uint32(dec))
		return b
	default:
		b := make([]byte, 8)
		binary.BigEndian.PutUint64(b, uint64(dec))
		return b
	}
}

// BinDec converts a binary string to its decimal representation.
func BinDec(bin []byte) int {
	return int(binary.BigEndian.Uint64(append(make([]byte, 8-len(bin)), bin...)))
}

// HexDec converts a hexadecimal string to its decimal representation.
func HexDec(hexStr string) *big.Int {
	i := new(big.Int)
	i.SetString(hexStr, 16)
	return i
}

// DecHex converts a decimal integer to its hexadecimal representation with an optional length.
func DecHex(dec *big.Int, length int) string {
	hexStr := fmt.Sprintf("%x", dec)
	if length > 0 {
		hexStr = fmt.Sprintf("%0*s", length, hexStr)
	}
	return hexStr
}

// ObjectToArray converts a struct to a map.
func ObjectToArray(object interface{}) (map[string]interface{}, error) {
	var result map[string]interface{}
	bytes, err := json.Marshal(object)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(bytes, &result)
	return result, err
}

// ArrayToObject converts a map to a struct.
func ArrayToObject(array map[string]interface{}, obj interface{}) error {
	bytes, err := json.Marshal(array)
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, obj)
}

// AlignedString converts a complex structure to an indented string representation.
func AlignedString(target interface{}, prefix string) string {
	var sb strings.Builder

	switch v := target.(type) {
	case map[string]interface{}:
		for key, item := range v {
			sb.WriteString(fmt.Sprintf("%s%s: ", prefix, key))
			if subMap, ok := item.(map[string]interface{}); ok {
				sb.WriteString("\n" + AlignedString(subMap, "  "+prefix))
			} else {
				sb.WriteString(fmt.Sprintf("%v\n", item))
			}
		}
	case struct{}:
		array, _ := ObjectToArray(v)
		return AlignedString(array, prefix)
	default:
		return fmt.Sprintf("%v", target)
	}
	return sb.String()
}

// Endpoint extracts the host and port from a URL.
func Endpoint(target string) string {
	u, err := url.Parse(target)
	if err != nil {
		return target
	}

	host := u.Hostname()
	port := u.Port()
	if port == "" {
		return host
	}
	return fmt.Sprintf("%s:%s", host, port)
}