mirror of
https://github.com/muun/recovery.git
synced 2025-11-13 07:11:45 -05:00
Release v0.1.0
This commit is contained in:
249
vendor/github.com/btcsuite/btcd/btcjson/cmdinfo.go
generated
vendored
Normal file
249
vendor/github.com/btcsuite/btcd/btcjson/cmdinfo.go
generated
vendored
Normal file
@@ -0,0 +1,249 @@
|
||||
// Copyright (c) 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcjson
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CmdMethod returns the method for the passed command. The provided command
|
||||
// type must be a registered type. All commands provided by this package are
|
||||
// registered by default.
|
||||
func CmdMethod(cmd interface{}) (string, error) {
|
||||
// Look up the cmd type and error out if not registered.
|
||||
rt := reflect.TypeOf(cmd)
|
||||
registerLock.RLock()
|
||||
method, ok := concreteTypeToMethod[rt]
|
||||
registerLock.RUnlock()
|
||||
if !ok {
|
||||
str := fmt.Sprintf("%q is not registered", method)
|
||||
return "", makeError(ErrUnregisteredMethod, str)
|
||||
}
|
||||
|
||||
return method, nil
|
||||
}
|
||||
|
||||
// MethodUsageFlags returns the usage flags for the passed command method. The
|
||||
// provided method must be associated with a registered type. All commands
|
||||
// provided by this package are registered by default.
|
||||
func MethodUsageFlags(method string) (UsageFlag, error) {
|
||||
// Look up details about the provided method and error out if not
|
||||
// registered.
|
||||
registerLock.RLock()
|
||||
info, ok := methodToInfo[method]
|
||||
registerLock.RUnlock()
|
||||
if !ok {
|
||||
str := fmt.Sprintf("%q is not registered", method)
|
||||
return 0, makeError(ErrUnregisteredMethod, str)
|
||||
}
|
||||
|
||||
return info.flags, nil
|
||||
}
|
||||
|
||||
// subStructUsage returns a string for use in the one-line usage for the given
|
||||
// sub struct. Note that this is specifically for fields which consist of
|
||||
// structs (or an array/slice of structs) as opposed to the top-level command
|
||||
// struct.
|
||||
//
|
||||
// Any fields that include a jsonrpcusage struct tag will use that instead of
|
||||
// being automatically generated.
|
||||
func subStructUsage(structType reflect.Type) string {
|
||||
numFields := structType.NumField()
|
||||
fieldUsages := make([]string, 0, numFields)
|
||||
for i := 0; i < structType.NumField(); i++ {
|
||||
rtf := structType.Field(i)
|
||||
|
||||
// When the field has a jsonrpcusage struct tag specified use
|
||||
// that instead of automatically generating it.
|
||||
if tag := rtf.Tag.Get("jsonrpcusage"); tag != "" {
|
||||
fieldUsages = append(fieldUsages, tag)
|
||||
continue
|
||||
}
|
||||
|
||||
// Create the name/value entry for the field while considering
|
||||
// the type of the field. Not all possible types are covered
|
||||
// here and when one of the types not specifically covered is
|
||||
// encountered, the field name is simply reused for the value.
|
||||
fieldName := strings.ToLower(rtf.Name)
|
||||
fieldValue := fieldName
|
||||
fieldKind := rtf.Type.Kind()
|
||||
switch {
|
||||
case isNumeric(fieldKind):
|
||||
if fieldKind == reflect.Float32 || fieldKind == reflect.Float64 {
|
||||
fieldValue = "n.nnn"
|
||||
} else {
|
||||
fieldValue = "n"
|
||||
}
|
||||
case fieldKind == reflect.String:
|
||||
fieldValue = `"value"`
|
||||
|
||||
case fieldKind == reflect.Struct:
|
||||
fieldValue = subStructUsage(rtf.Type)
|
||||
|
||||
case fieldKind == reflect.Array || fieldKind == reflect.Slice:
|
||||
fieldValue = subArrayUsage(rtf.Type, fieldName)
|
||||
}
|
||||
|
||||
usage := fmt.Sprintf("%q:%s", fieldName, fieldValue)
|
||||
fieldUsages = append(fieldUsages, usage)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("{%s}", strings.Join(fieldUsages, ","))
|
||||
}
|
||||
|
||||
// subArrayUsage returns a string for use in the one-line usage for the given
|
||||
// array or slice. It also contains logic to convert plural field names to
|
||||
// singular so the generated usage string reads better.
|
||||
func subArrayUsage(arrayType reflect.Type, fieldName string) string {
|
||||
// Convert plural field names to singular. Only works for English.
|
||||
singularFieldName := fieldName
|
||||
if strings.HasSuffix(fieldName, "ies") {
|
||||
singularFieldName = strings.TrimSuffix(fieldName, "ies")
|
||||
singularFieldName = singularFieldName + "y"
|
||||
} else if strings.HasSuffix(fieldName, "es") {
|
||||
singularFieldName = strings.TrimSuffix(fieldName, "es")
|
||||
} else if strings.HasSuffix(fieldName, "s") {
|
||||
singularFieldName = strings.TrimSuffix(fieldName, "s")
|
||||
}
|
||||
|
||||
elemType := arrayType.Elem()
|
||||
switch elemType.Kind() {
|
||||
case reflect.String:
|
||||
return fmt.Sprintf("[%q,...]", singularFieldName)
|
||||
|
||||
case reflect.Struct:
|
||||
return fmt.Sprintf("[%s,...]", subStructUsage(elemType))
|
||||
}
|
||||
|
||||
// Fall back to simply showing the field name in array syntax.
|
||||
return fmt.Sprintf(`[%s,...]`, singularFieldName)
|
||||
}
|
||||
|
||||
// fieldUsage returns a string for use in the one-line usage for the struct
|
||||
// field of a command.
|
||||
//
|
||||
// Any fields that include a jsonrpcusage struct tag will use that instead of
|
||||
// being automatically generated.
|
||||
func fieldUsage(structField reflect.StructField, defaultVal *reflect.Value) string {
|
||||
// When the field has a jsonrpcusage struct tag specified use that
|
||||
// instead of automatically generating it.
|
||||
if tag := structField.Tag.Get("jsonrpcusage"); tag != "" {
|
||||
return tag
|
||||
}
|
||||
|
||||
// Indirect the pointer if needed.
|
||||
fieldType := structField.Type
|
||||
if fieldType.Kind() == reflect.Ptr {
|
||||
fieldType = fieldType.Elem()
|
||||
}
|
||||
|
||||
// When there is a default value, it must also be a pointer due to the
|
||||
// rules enforced by RegisterCmd.
|
||||
if defaultVal != nil {
|
||||
indirect := defaultVal.Elem()
|
||||
defaultVal = &indirect
|
||||
}
|
||||
|
||||
// Handle certain types uniquely to provide nicer usage.
|
||||
fieldName := strings.ToLower(structField.Name)
|
||||
switch fieldType.Kind() {
|
||||
case reflect.String:
|
||||
if defaultVal != nil {
|
||||
return fmt.Sprintf("%s=%q", fieldName,
|
||||
defaultVal.Interface())
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%q", fieldName)
|
||||
|
||||
case reflect.Array, reflect.Slice:
|
||||
return subArrayUsage(fieldType, fieldName)
|
||||
|
||||
case reflect.Struct:
|
||||
return subStructUsage(fieldType)
|
||||
}
|
||||
|
||||
// Simply return the field name when none of the above special cases
|
||||
// apply.
|
||||
if defaultVal != nil {
|
||||
return fmt.Sprintf("%s=%v", fieldName, defaultVal.Interface())
|
||||
}
|
||||
return fieldName
|
||||
}
|
||||
|
||||
// methodUsageText returns a one-line usage string for the provided command and
|
||||
// method info. This is the main work horse for the exported MethodUsageText
|
||||
// function.
|
||||
func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method string) string {
|
||||
// Generate the individual usage for each field in the command. Several
|
||||
// simplifying assumptions are made here because the RegisterCmd
|
||||
// function has already rigorously enforced the layout.
|
||||
rt := rtp.Elem()
|
||||
numFields := rt.NumField()
|
||||
reqFieldUsages := make([]string, 0, numFields)
|
||||
optFieldUsages := make([]string, 0, numFields)
|
||||
for i := 0; i < numFields; i++ {
|
||||
rtf := rt.Field(i)
|
||||
var isOptional bool
|
||||
if kind := rtf.Type.Kind(); kind == reflect.Ptr {
|
||||
isOptional = true
|
||||
}
|
||||
|
||||
var defaultVal *reflect.Value
|
||||
if defVal, ok := defaults[i]; ok {
|
||||
defaultVal = &defVal
|
||||
}
|
||||
|
||||
// Add human-readable usage to the appropriate slice that is
|
||||
// later used to generate the one-line usage.
|
||||
usage := fieldUsage(rtf, defaultVal)
|
||||
if isOptional {
|
||||
optFieldUsages = append(optFieldUsages, usage)
|
||||
} else {
|
||||
reqFieldUsages = append(reqFieldUsages, usage)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate and return the one-line usage string.
|
||||
usageStr := method
|
||||
if len(reqFieldUsages) > 0 {
|
||||
usageStr += " " + strings.Join(reqFieldUsages, " ")
|
||||
}
|
||||
if len(optFieldUsages) > 0 {
|
||||
usageStr += fmt.Sprintf(" (%s)", strings.Join(optFieldUsages, " "))
|
||||
}
|
||||
return usageStr
|
||||
}
|
||||
|
||||
// MethodUsageText returns a one-line usage string for the provided method. The
|
||||
// provided method must be associated with a registered type. All commands
|
||||
// provided by this package are registered by default.
|
||||
func MethodUsageText(method string) (string, error) {
|
||||
// Look up details about the provided method and error out if not
|
||||
// registered.
|
||||
registerLock.RLock()
|
||||
rtp, ok := methodToConcreteType[method]
|
||||
info := methodToInfo[method]
|
||||
registerLock.RUnlock()
|
||||
if !ok {
|
||||
str := fmt.Sprintf("%q is not registered", method)
|
||||
return "", makeError(ErrUnregisteredMethod, str)
|
||||
}
|
||||
|
||||
// When the usage for this method has already been generated, simply
|
||||
// return it.
|
||||
if info.usage != "" {
|
||||
return info.usage, nil
|
||||
}
|
||||
|
||||
// Generate and store the usage string for future calls and return it.
|
||||
usage := methodUsageText(rtp, info.defaults, method)
|
||||
registerLock.Lock()
|
||||
info.usage = usage
|
||||
methodToInfo[method] = info
|
||||
registerLock.Unlock()
|
||||
return usage, nil
|
||||
}
|
||||
Reference in New Issue
Block a user