option.go 3.31 KB
Newer Older
Matt Bell's avatar
Matt Bell committed
1 2
package commands

3 4
import (
	"reflect"
Matt Bell's avatar
Matt Bell committed
5

6 7
	"github.com/jbenet/go-ipfs/util"
)
8

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
9
// Types of Command options
Matt Bell's avatar
Matt Bell committed
10
const (
Matt Bell's avatar
Matt Bell committed
11 12 13 14
	Invalid = reflect.Invalid
	Bool    = reflect.Bool
	Int     = reflect.Int
	Uint    = reflect.Uint
15
	Float   = reflect.Float64
Matt Bell's avatar
Matt Bell committed
16
	String  = reflect.String
Matt Bell's avatar
Matt Bell committed
17 18 19 20
)

// Option is used to specify a field that will be provided by a consumer
type Option struct {
21 22 23
	Names       []string     // a list of unique names to
	Type        reflect.Kind // value must be this type
	Description string       // a short string to describe this option
24

25
	// MAYBE_TODO: add more features(?):
Matt Bell's avatar
Matt Bell committed
26 27
	//Default interface{} // the default value (ignored if `Required` is true)
	//Required bool       // whether or not the option must be provided
Matt Bell's avatar
Matt Bell committed
28
}
29

30 31 32
// constructor helper functions
func NewOption(kind reflect.Kind, names ...string) Option {
	if len(names) < 2 {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
33
		// FIXME(btc) don't panic (fix_before_merge)
34 35 36 37
		panic("Options require at least two string values (name and description)")
	}

	desc := names[len(names)-1]
38
	names = names[:len(names)-1]
39 40 41 42 43 44 45 46

	return Option{
		Names:       names,
		Type:        kind,
		Description: desc,
	}
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
47 48 49 50 51 52
// TODO handle description separately. this will take care of the panic case in
// NewOption

// For all func {Type}Option(...string) functions, the last variadic argument
// is treated as the description field.

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
func BoolOption(names ...string) Option {
	return NewOption(Bool, names...)
}
func IntOption(names ...string) Option {
	return NewOption(Int, names...)
}
func UintOption(names ...string) Option {
	return NewOption(Uint, names...)
}
func FloatOption(names ...string) Option {
	return NewOption(Float, names...)
}
func StringOption(names ...string) Option {
	return NewOption(String, names...)
}

69 70 71 72 73 74 75 76 77 78 79
type OptionValue struct {
	value interface{}
	found bool
}

// Found returns true if the option value was provided by the user (not a default value)
func (ov OptionValue) Found() bool {
	return ov.found
}

// value accessor methods, gets the value as a certain type
80 81 82 83
func (ov OptionValue) Bool() (value bool, found bool, err error) {
	if !ov.found {
		return false, false, nil
	}
84 85
	val, ok := ov.value.(bool)
	if !ok {
86
		err = util.ErrCast()
87
	}
88
	return val, ov.found, err
89
}
90

91
func (ov OptionValue) Int() (value int, found bool, err error) {
92 93 94
	if !ov.found {
		return 0, false, nil
	}
95 96
	val, ok := ov.value.(int)
	if !ok {
97
		err = util.ErrCast()
98
	}
99
	return val, ov.found, err
100
}
101

102
func (ov OptionValue) Uint() (value uint, found bool, err error) {
103 104 105
	if !ov.found {
		return 0, false, nil
	}
106 107
	val, ok := ov.value.(uint)
	if !ok {
108
		err = util.ErrCast()
109
	}
110
	return val, ov.found, err
111
}
112

113
func (ov OptionValue) Float() (value float64, found bool, err error) {
114 115 116
	if !ov.found {
		return 0, false, nil
	}
117 118
	val, ok := ov.value.(float64)
	if !ok {
119
		err = util.ErrCast()
120
	}
121
	return val, ov.found, err
122
}
123

124
func (ov OptionValue) String() (value string, found bool, err error) {
125 126 127
	if !ov.found {
		return "", false, nil
	}
128 129
	val, ok := ov.value.(string)
	if !ok {
130
		err = util.ErrCast()
131
	}
132
	return val, ov.found, err
133 134
}

Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
135 136 137 138 139 140
// Flag names
const (
	EncShort = "enc"
	EncLong  = "encoding"
)

141
// options that are used by this package
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
142
var globalOptions = []Option{
143 144
	Option{[]string{EncShort, EncLong}, String,
		"The encoding type the output should be encoded with (json, xml, or text)"},
145
}
Matt Bell's avatar
Matt Bell committed
146

147
// the above array of Options, wrapped in a Command
Juan Batiz-Benet's avatar
Juan Batiz-Benet committed
148
var globalCommand = &Command{
Matt Bell's avatar
Matt Bell committed
149
	Options: globalOptions,
150
}