2020-03-03 20:09:47 +00:00
|
|
|
package flags
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
2024-07-09 18:24:39 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
2020-03-03 20:09:47 +00:00
|
|
|
)
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// Address is a wrapper for a Uint160 with flag.Value methods.
|
2020-03-10 06:54:05 +00:00
|
|
|
type Address struct {
|
|
|
|
IsSet bool
|
|
|
|
Value util.Uint160
|
|
|
|
}
|
2020-03-03 20:09:47 +00:00
|
|
|
|
2024-07-09 18:24:39 +00:00
|
|
|
// AddressFlag is a flag with type Uint160.
|
2020-03-03 20:09:47 +00:00
|
|
|
type AddressFlag struct {
|
2024-07-09 18:24:39 +00:00
|
|
|
Name string
|
|
|
|
Usage string
|
|
|
|
Value Address
|
|
|
|
Aliases []string
|
|
|
|
Required bool
|
|
|
|
Hidden bool
|
|
|
|
Action func(*cli.Context, string) error
|
2020-03-03 20:09:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ flag.Value = (*Address)(nil)
|
|
|
|
_ cli.Flag = AddressFlag{}
|
|
|
|
)
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// String implements the fmt.Stringer interface.
|
2020-03-03 20:09:47 +00:00
|
|
|
func (a Address) String() string {
|
2020-03-10 06:54:05 +00:00
|
|
|
return address.Uint160ToString(a.Value)
|
2020-03-03 20:09:47 +00:00
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// Set implements the flag.Value interface.
|
2020-03-03 20:09:47 +00:00
|
|
|
func (a *Address) Set(s string) error {
|
2021-02-18 09:50:12 +00:00
|
|
|
addr, err := ParseAddress(s)
|
2020-03-03 20:09:47 +00:00
|
|
|
if err != nil {
|
2024-07-09 18:24:39 +00:00
|
|
|
return cli.Exit(err, 1)
|
2020-03-03 20:09:47 +00:00
|
|
|
}
|
2020-03-10 06:54:05 +00:00
|
|
|
a.IsSet = true
|
|
|
|
a.Value = addr
|
2020-03-03 20:09:47 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// Uint160 casts an address to Uint160.
|
2020-03-03 20:09:47 +00:00
|
|
|
func (a *Address) Uint160() (u util.Uint160) {
|
2020-03-10 06:54:05 +00:00
|
|
|
if !a.IsSet {
|
|
|
|
// It is a programmer error to call this method without
|
|
|
|
// checking if the value was provided.
|
|
|
|
panic("address was not set")
|
|
|
|
}
|
|
|
|
return a.Value
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsSet checks if flag was set to a non-default value.
|
|
|
|
func (f AddressFlag) IsSet() bool {
|
|
|
|
return f.Value.IsSet
|
2020-03-03 20:09:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// String returns a readable representation of this value
|
2021-05-12 20:17:03 +00:00
|
|
|
// (for usage defaults).
|
2020-03-03 20:09:47 +00:00
|
|
|
func (f AddressFlag) String() string {
|
|
|
|
var names []string
|
2024-07-09 18:24:39 +00:00
|
|
|
for _, name := range f.Names() {
|
2020-03-03 20:09:47 +00:00
|
|
|
names = append(names, getNameHelp(name))
|
2024-07-09 18:24:39 +00:00
|
|
|
}
|
2020-03-03 20:09:47 +00:00
|
|
|
|
|
|
|
return strings.Join(names, ", ") + "\t" + f.Usage
|
|
|
|
}
|
|
|
|
|
|
|
|
func getNameHelp(name string) string {
|
|
|
|
if len(name) == 1 {
|
|
|
|
return fmt.Sprintf("-%s value", name)
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("--%s value", name)
|
|
|
|
}
|
|
|
|
|
2024-07-09 18:24:39 +00:00
|
|
|
// Names returns the names of the flag.
|
|
|
|
func (f AddressFlag) Names() []string {
|
|
|
|
return cli.FlagNames(f.Name, f.Aliases)
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsRequired returns whether the flag is required.
|
|
|
|
func (f AddressFlag) IsRequired() bool {
|
|
|
|
return f.Required
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsVisible returns true if the flag is not hidden, otherwise false.
|
|
|
|
func (f AddressFlag) IsVisible() bool {
|
|
|
|
return !f.Hidden
|
|
|
|
}
|
|
|
|
|
|
|
|
// TakesValue returns true of the flag takes a value, otherwise false.
|
|
|
|
func (f AddressFlag) TakesValue() bool {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetUsage returns the usage string for the flag.
|
|
|
|
func (f AddressFlag) GetUsage() string {
|
|
|
|
return f.Usage
|
2020-03-03 20:09:47 +00:00
|
|
|
}
|
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// Apply populates the flag given the flag set and environment.
|
2021-05-12 20:17:03 +00:00
|
|
|
// Ignores errors.
|
2024-07-09 18:24:39 +00:00
|
|
|
func (f AddressFlag) Apply(set *flag.FlagSet) error {
|
|
|
|
for _, name := range f.Names() {
|
2020-03-03 20:09:47 +00:00
|
|
|
set.Var(&f.Value, name, f.Usage)
|
2024-07-09 18:24:39 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// RunAction executes flag action if set.
|
|
|
|
func (f AddressFlag) RunAction(c *cli.Context) error {
|
|
|
|
if f.Action != nil {
|
|
|
|
return f.Action(c, address.Uint160ToString(f.Value.Value))
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetValue returns the flags value as string representation.
|
|
|
|
func (f AddressFlag) GetValue() string {
|
|
|
|
return address.Uint160ToString(f.Value.Value)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get returns the flag’s value in the given Context.
|
|
|
|
func (f AddressFlag) Get(ctx *cli.Context) Address {
|
|
|
|
adr := ctx.Generic(f.Name).(*Address)
|
|
|
|
return *adr
|
2020-03-03 20:09:47 +00:00
|
|
|
}
|
2021-02-18 09:50:12 +00:00
|
|
|
|
2022-04-20 18:30:09 +00:00
|
|
|
// ParseAddress parses a Uint160 from either an LE string or an address.
|
2021-02-18 09:50:12 +00:00
|
|
|
func ParseAddress(s string) (util.Uint160, error) {
|
|
|
|
const uint160size = 2 * util.Uint160Size
|
|
|
|
switch len(s) {
|
|
|
|
case uint160size, uint160size + 2:
|
|
|
|
return util.Uint160DecodeStringLE(strings.TrimPrefix(s, "0x"))
|
|
|
|
default:
|
|
|
|
return address.StringToUint160(s)
|
|
|
|
}
|
|
|
|
}
|