tutus-chain/cli/flags/address.go

147 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package flags
import (
"flag"
"fmt"
"strings"
"github.com/tutus-one/tutus-chain/pkg/encoding/address"
"github.com/tutus-one/tutus-chain/pkg/util"
"github.com/urfave/cli/v2"
)
// Address is a wrapper for a Uint160 with flag.Value methods.
type Address struct {
IsSet bool
Value util.Uint160
}
// AddressFlag is a flag with type Uint160.
type AddressFlag struct {
Name string
Usage string
Value Address
Aliases []string
Required bool
Hidden bool
Action func(*cli.Context, string) error
}
var (
_ flag.Value = (*Address)(nil)
_ cli.Flag = AddressFlag{}
)
// String implements the fmt.Stringer interface.
func (a Address) String() string {
return address.Uint160ToString(a.Value)
}
// Set implements the flag.Value interface.
func (a *Address) Set(s string) error {
addr, err := ParseAddress(s)
if err != nil {
return cli.Exit(err, 1)
}
a.IsSet = true
a.Value = addr
return nil
}
// Uint160 casts an address to Uint160.
func (a *Address) Uint160() (u util.Uint160) {
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
}
// String returns a readable representation of this value
// (for usage defaults).
func (f AddressFlag) String() string {
var names []string
for _, name := range f.Names() {
names = append(names, getNameHelp(name))
}
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)
}
// 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
}
// Apply populates the flag given the flag set and environment.
// Ignores errors.
func (f AddressFlag) Apply(set *flag.FlagSet) error {
for _, name := range f.Names() {
set.Var(&f.Value, name, f.Usage)
}
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 flags value in the given Context.
func (f AddressFlag) Get(ctx *cli.Context) Address {
adr := ctx.Generic(f.Name).(*Address)
return *adr
}
// ParseAddress parses a Uint160 from either an LE string or an address.
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)
}
}