github.com/hustcat/docker@v1.3.3-0.20160314103604-901c67a8eeab/opts/opts.go (about)

     1  package opts
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"regexp"
     7  	"strings"
     8  )
     9  
    10  var (
    11  	alphaRegexp  = regexp.MustCompile(`[a-zA-Z]`)
    12  	domainRegexp = regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
    13  )
    14  
    15  // ListOpts holds a list of values and a validation function.
    16  type ListOpts struct {
    17  	values    *[]string
    18  	validator ValidatorFctType
    19  }
    20  
    21  // NewListOpts creates a new ListOpts with the specified validator.
    22  func NewListOpts(validator ValidatorFctType) ListOpts {
    23  	var values []string
    24  	return *NewListOptsRef(&values, validator)
    25  }
    26  
    27  // NewListOptsRef creates a new ListOpts with the specified values and validator.
    28  func NewListOptsRef(values *[]string, validator ValidatorFctType) *ListOpts {
    29  	return &ListOpts{
    30  		values:    values,
    31  		validator: validator,
    32  	}
    33  }
    34  
    35  func (opts *ListOpts) String() string {
    36  	return fmt.Sprintf("%v", []string((*opts.values)))
    37  }
    38  
    39  // Set validates if needed the input value and add it to the
    40  // internal slice.
    41  func (opts *ListOpts) Set(value string) error {
    42  	if opts.validator != nil {
    43  		v, err := opts.validator(value)
    44  		if err != nil {
    45  			return err
    46  		}
    47  		value = v
    48  	}
    49  	(*opts.values) = append((*opts.values), value)
    50  	return nil
    51  }
    52  
    53  // Delete removes the specified element from the slice.
    54  func (opts *ListOpts) Delete(key string) {
    55  	for i, k := range *opts.values {
    56  		if k == key {
    57  			(*opts.values) = append((*opts.values)[:i], (*opts.values)[i+1:]...)
    58  			return
    59  		}
    60  	}
    61  }
    62  
    63  // GetMap returns the content of values in a map in order to avoid
    64  // duplicates.
    65  func (opts *ListOpts) GetMap() map[string]struct{} {
    66  	ret := make(map[string]struct{})
    67  	for _, k := range *opts.values {
    68  		ret[k] = struct{}{}
    69  	}
    70  	return ret
    71  }
    72  
    73  // GetAll returns the values of slice.
    74  func (opts *ListOpts) GetAll() []string {
    75  	return (*opts.values)
    76  }
    77  
    78  // GetAllOrEmpty returns the values of the slice
    79  // or an empty slice when there are no values.
    80  func (opts *ListOpts) GetAllOrEmpty() []string {
    81  	v := *opts.values
    82  	if v == nil {
    83  		return make([]string, 0)
    84  	}
    85  	return v
    86  }
    87  
    88  // Get checks the existence of the specified key.
    89  func (opts *ListOpts) Get(key string) bool {
    90  	for _, k := range *opts.values {
    91  		if k == key {
    92  			return true
    93  		}
    94  	}
    95  	return false
    96  }
    97  
    98  // Len returns the amount of element in the slice.
    99  func (opts *ListOpts) Len() int {
   100  	return len((*opts.values))
   101  }
   102  
   103  // NamedOption is an interface that list and map options
   104  // with names implement.
   105  type NamedOption interface {
   106  	Name() string
   107  }
   108  
   109  // NamedListOpts is a ListOpts with a configuration name.
   110  // This struct is useful to keep reference to the assigned
   111  // field name in the internal configuration struct.
   112  type NamedListOpts struct {
   113  	name string
   114  	ListOpts
   115  }
   116  
   117  var _ NamedOption = &NamedListOpts{}
   118  
   119  // NewNamedListOptsRef creates a reference to a new NamedListOpts struct.
   120  func NewNamedListOptsRef(name string, values *[]string, validator ValidatorFctType) *NamedListOpts {
   121  	return &NamedListOpts{
   122  		name:     name,
   123  		ListOpts: *NewListOptsRef(values, validator),
   124  	}
   125  }
   126  
   127  // Name returns the name of the NamedListOpts in the configuration.
   128  func (o *NamedListOpts) Name() string {
   129  	return o.name
   130  }
   131  
   132  //MapOpts holds a map of values and a validation function.
   133  type MapOpts struct {
   134  	values    map[string]string
   135  	validator ValidatorFctType
   136  }
   137  
   138  // Set validates if needed the input value and add it to the
   139  // internal map, by splitting on '='.
   140  func (opts *MapOpts) Set(value string) error {
   141  	if opts.validator != nil {
   142  		v, err := opts.validator(value)
   143  		if err != nil {
   144  			return err
   145  		}
   146  		value = v
   147  	}
   148  	vals := strings.SplitN(value, "=", 2)
   149  	if len(vals) == 1 {
   150  		(opts.values)[vals[0]] = ""
   151  	} else {
   152  		(opts.values)[vals[0]] = vals[1]
   153  	}
   154  	return nil
   155  }
   156  
   157  // GetAll returns the values of MapOpts as a map.
   158  func (opts *MapOpts) GetAll() map[string]string {
   159  	return opts.values
   160  }
   161  
   162  func (opts *MapOpts) String() string {
   163  	return fmt.Sprintf("%v", map[string]string((opts.values)))
   164  }
   165  
   166  // NewMapOpts creates a new MapOpts with the specified map of values and a validator.
   167  func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
   168  	if values == nil {
   169  		values = make(map[string]string)
   170  	}
   171  	return &MapOpts{
   172  		values:    values,
   173  		validator: validator,
   174  	}
   175  }
   176  
   177  // NamedMapOpts is a MapOpts struct with a configuration name.
   178  // This struct is useful to keep reference to the assigned
   179  // field name in the internal configuration struct.
   180  type NamedMapOpts struct {
   181  	name string
   182  	MapOpts
   183  }
   184  
   185  var _ NamedOption = &NamedMapOpts{}
   186  
   187  // NewNamedMapOpts creates a reference to a new NamedMapOpts struct.
   188  func NewNamedMapOpts(name string, values map[string]string, validator ValidatorFctType) *NamedMapOpts {
   189  	return &NamedMapOpts{
   190  		name:    name,
   191  		MapOpts: *NewMapOpts(values, validator),
   192  	}
   193  }
   194  
   195  // Name returns the name of the NamedMapOpts in the configuration.
   196  func (o *NamedMapOpts) Name() string {
   197  	return o.name
   198  }
   199  
   200  // ValidatorFctType defines a validator function that returns a validated string and/or an error.
   201  type ValidatorFctType func(val string) (string, error)
   202  
   203  // ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
   204  type ValidatorFctListType func(val string) ([]string, error)
   205  
   206  // ValidateIPAddress validates an Ip address.
   207  func ValidateIPAddress(val string) (string, error) {
   208  	var ip = net.ParseIP(strings.TrimSpace(val))
   209  	if ip != nil {
   210  		return ip.String(), nil
   211  	}
   212  	return "", fmt.Errorf("%s is not an ip address", val)
   213  }
   214  
   215  // ValidateDNSSearch validates domain for resolvconf search configuration.
   216  // A zero length domain is represented by a dot (.).
   217  func ValidateDNSSearch(val string) (string, error) {
   218  	if val = strings.Trim(val, " "); val == "." {
   219  		return val, nil
   220  	}
   221  	return validateDomain(val)
   222  }
   223  
   224  func validateDomain(val string) (string, error) {
   225  	if alphaRegexp.FindString(val) == "" {
   226  		return "", fmt.Errorf("%s is not a valid domain", val)
   227  	}
   228  	ns := domainRegexp.FindSubmatch([]byte(val))
   229  	if len(ns) > 0 && len(ns[1]) < 255 {
   230  		return string(ns[1]), nil
   231  	}
   232  	return "", fmt.Errorf("%s is not a valid domain", val)
   233  }
   234  
   235  // ValidateLabel validates that the specified string is a valid label, and returns it.
   236  // Labels are in the form on key=value.
   237  func ValidateLabel(val string) (string, error) {
   238  	if strings.Count(val, "=") < 1 {
   239  		return "", fmt.Errorf("bad attribute format: %s", val)
   240  	}
   241  	return val, nil
   242  }