github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/command/swarm/ipnet_slice.go (about) 1 package swarm 2 3 import ( 4 "bytes" 5 "encoding/csv" 6 "fmt" 7 "io" 8 "net" 9 "strings" 10 ) 11 12 // -- ipNetSlice Value 13 type ipNetSliceValue struct { 14 value *[]net.IPNet 15 changed bool 16 } 17 18 func newIPNetSliceValue(val []net.IPNet, p *[]net.IPNet) *ipNetSliceValue { 19 ipnsv := new(ipNetSliceValue) 20 ipnsv.value = p 21 *ipnsv.value = val 22 return ipnsv 23 } 24 25 // Set converts, and assigns, the comma-separated IPNet argument string representation as the []net.IPNet value of this flag. 26 // If Set is called on a flag that already has a []net.IPNet assigned, the newly converted values will be appended. 27 func (s *ipNetSliceValue) Set(val string) error { 28 29 // remove all quote characters 30 rmQuote := strings.NewReplacer(`"`, "", `'`, "", "`", "") 31 32 // read flag arguments with CSV parser 33 ipNetStrSlice, err := readAsCSV(rmQuote.Replace(val)) 34 if err != nil && err != io.EOF { 35 return err 36 } 37 38 // parse ip values into slice 39 out := make([]net.IPNet, 0, len(ipNetStrSlice)) 40 for _, ipNetStr := range ipNetStrSlice { 41 _, n, err := net.ParseCIDR(strings.TrimSpace(ipNetStr)) 42 if err != nil { 43 return fmt.Errorf("invalid string being converted to CIDR: %s", ipNetStr) 44 } 45 out = append(out, *n) 46 } 47 48 if !s.changed { 49 *s.value = out 50 } else { 51 *s.value = append(*s.value, out...) 52 } 53 54 s.changed = true 55 56 return nil 57 } 58 59 // Type returns a string that uniquely represents this flag's type. 60 func (s *ipNetSliceValue) Type() string { 61 return "ipNetSlice" 62 } 63 64 // String defines a "native" format for this net.IPNet slice flag value. 65 func (s *ipNetSliceValue) String() string { 66 67 ipNetStrSlice := make([]string, len(*s.value)) 68 for i, n := range *s.value { 69 ipNetStrSlice[i] = n.String() 70 } 71 72 out, _ := writeAsCSV(ipNetStrSlice) 73 return "[" + out + "]" 74 } 75 76 func readAsCSV(val string) ([]string, error) { 77 if val == "" { 78 return []string{}, nil 79 } 80 stringReader := strings.NewReader(val) 81 csvReader := csv.NewReader(stringReader) 82 return csvReader.Read() 83 } 84 85 func writeAsCSV(vals []string) (string, error) { 86 b := &bytes.Buffer{} 87 w := csv.NewWriter(b) 88 err := w.Write(vals) 89 if err != nil { 90 return "", err 91 } 92 w.Flush() 93 return strings.TrimSuffix(b.String(), "\n"), nil 94 }