github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/cli/flags/address.go (about)

     1  package flags
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/nspcc-dev/neo-go/pkg/encoding/address"
     9  	"github.com/nspcc-dev/neo-go/pkg/util"
    10  	"github.com/urfave/cli"
    11  )
    12  
    13  // Address is a wrapper for a Uint160 with flag.Value methods.
    14  type Address struct {
    15  	IsSet bool
    16  	Value util.Uint160
    17  }
    18  
    19  // AddressFlag is a flag with type string.
    20  type AddressFlag struct {
    21  	Name  string
    22  	Usage string
    23  	Value Address
    24  }
    25  
    26  var (
    27  	_ flag.Value = (*Address)(nil)
    28  	_ cli.Flag   = AddressFlag{}
    29  )
    30  
    31  // String implements the fmt.Stringer interface.
    32  func (a Address) String() string {
    33  	return address.Uint160ToString(a.Value)
    34  }
    35  
    36  // Set implements the flag.Value interface.
    37  func (a *Address) Set(s string) error {
    38  	addr, err := ParseAddress(s)
    39  	if err != nil {
    40  		return cli.NewExitError(err, 1)
    41  	}
    42  	a.IsSet = true
    43  	a.Value = addr
    44  	return nil
    45  }
    46  
    47  // Uint160 casts an address to Uint160.
    48  func (a *Address) Uint160() (u util.Uint160) {
    49  	if !a.IsSet {
    50  		// It is a programmer error to call this method without
    51  		// checking if the value was provided.
    52  		panic("address was not set")
    53  	}
    54  	return a.Value
    55  }
    56  
    57  // IsSet checks if flag was set to a non-default value.
    58  func (f AddressFlag) IsSet() bool {
    59  	return f.Value.IsSet
    60  }
    61  
    62  // String returns a readable representation of this value
    63  // (for usage defaults).
    64  func (f AddressFlag) String() string {
    65  	var names []string
    66  	eachName(f.Name, func(name string) {
    67  		names = append(names, getNameHelp(name))
    68  	})
    69  
    70  	return strings.Join(names, ", ") + "\t" + f.Usage
    71  }
    72  
    73  func getNameHelp(name string) string {
    74  	if len(name) == 1 {
    75  		return fmt.Sprintf("-%s value", name)
    76  	}
    77  	return fmt.Sprintf("--%s value", name)
    78  }
    79  
    80  // GetName returns the name of the flag.
    81  func (f AddressFlag) GetName() string {
    82  	return f.Name
    83  }
    84  
    85  // Apply populates the flag given the flag set and environment.
    86  // Ignores errors.
    87  func (f AddressFlag) Apply(set *flag.FlagSet) {
    88  	eachName(f.Name, func(name string) {
    89  		set.Var(&f.Value, name, f.Usage)
    90  	})
    91  }
    92  
    93  // ParseAddress parses a Uint160 from either an LE string or an address.
    94  func ParseAddress(s string) (util.Uint160, error) {
    95  	const uint160size = 2 * util.Uint160Size
    96  	switch len(s) {
    97  	case uint160size, uint160size + 2:
    98  		return util.Uint160DecodeStringLE(strings.TrimPrefix(s, "0x"))
    99  	default:
   100  		return address.StringToUint160(s)
   101  	}
   102  }