github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/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  //MapOpts holds a map of values and a validation function.
   104  type MapOpts struct {
   105  	values    map[string]string
   106  	validator ValidatorFctType
   107  }
   108  
   109  // Set validates if needed the input value and add it to the
   110  // internal map, by splitting on '='.
   111  func (opts *MapOpts) Set(value string) error {
   112  	if opts.validator != nil {
   113  		v, err := opts.validator(value)
   114  		if err != nil {
   115  			return err
   116  		}
   117  		value = v
   118  	}
   119  	vals := strings.SplitN(value, "=", 2)
   120  	if len(vals) == 1 {
   121  		(opts.values)[vals[0]] = ""
   122  	} else {
   123  		(opts.values)[vals[0]] = vals[1]
   124  	}
   125  	return nil
   126  }
   127  
   128  // GetAll returns the values of MapOpts as a map.
   129  func (opts *MapOpts) GetAll() map[string]string {
   130  	return opts.values
   131  }
   132  
   133  func (opts *MapOpts) String() string {
   134  	return fmt.Sprintf("%v", map[string]string((opts.values)))
   135  }
   136  
   137  // NewMapOpts creates a new MapOpts with the specified map of values and a validator.
   138  func NewMapOpts(values map[string]string, validator ValidatorFctType) *MapOpts {
   139  	if values == nil {
   140  		values = make(map[string]string)
   141  	}
   142  	return &MapOpts{
   143  		values:    values,
   144  		validator: validator,
   145  	}
   146  }
   147  
   148  // ValidatorFctType defines a validator function that returns a validated string and/or an error.
   149  type ValidatorFctType func(val string) (string, error)
   150  
   151  // ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
   152  type ValidatorFctListType func(val string) ([]string, error)
   153  
   154  // ValidateIPAddress validates an Ip address.
   155  func ValidateIPAddress(val string) (string, error) {
   156  	var ip = net.ParseIP(strings.TrimSpace(val))
   157  	if ip != nil {
   158  		return ip.String(), nil
   159  	}
   160  	return "", fmt.Errorf("%s is not an ip address", val)
   161  }
   162  
   163  // ValidateDNSSearch validates domain for resolvconf search configuration.
   164  // A zero length domain is represented by a dot (.).
   165  func ValidateDNSSearch(val string) (string, error) {
   166  	if val = strings.Trim(val, " "); val == "." {
   167  		return val, nil
   168  	}
   169  	return validateDomain(val)
   170  }
   171  
   172  func validateDomain(val string) (string, error) {
   173  	if alphaRegexp.FindString(val) == "" {
   174  		return "", fmt.Errorf("%s is not a valid domain", val)
   175  	}
   176  	ns := domainRegexp.FindSubmatch([]byte(val))
   177  	if len(ns) > 0 && len(ns[1]) < 255 {
   178  		return string(ns[1]), nil
   179  	}
   180  	return "", fmt.Errorf("%s is not a valid domain", val)
   181  }
   182  
   183  // ValidateLabel validates that the specified string is a valid label, and returns it.
   184  // Labels are in the form on key=value.
   185  func ValidateLabel(val string) (string, error) {
   186  	if strings.Count(val, "=") < 1 {
   187  		return "", fmt.Errorf("bad attribute format: %s", val)
   188  	}
   189  	return val, nil
   190  }