FormatPorts returns a human-friendly string. Consecutive runs of at least five ports are collapsed into ranges (e.g. "8000-8006").
(ports []int)
| 92 | // FormatPorts returns a human-friendly string. Consecutive runs of at least |
| 93 | // five ports are collapsed into ranges (e.g. "8000-8006"). |
| 94 | func FormatPorts(ports []int) string { |
| 95 | if len(ports) == 0 { |
| 96 | return "" |
| 97 | } |
| 98 | |
| 99 | sorted := append([]int(nil), ports...) |
| 100 | sort.Ints(sorted) |
| 101 | |
| 102 | unique := make([]int, 0, len(sorted)) |
| 103 | for _, p := range sorted { |
| 104 | if len(unique) == 0 || unique[len(unique)-1] != p { |
| 105 | unique = append(unique, p) |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | var parts []string |
| 110 | start := unique[0] |
| 111 | prev := unique[0] |
| 112 | |
| 113 | flush := func(s, e int) { |
| 114 | if e-s+1 >= minRangeDisplay { |
| 115 | parts = append(parts, fmt.Sprintf("%d-%d", s, e)) |
| 116 | return |
| 117 | } |
| 118 | for p := s; p <= e; p++ { |
| 119 | parts = append(parts, strconv.Itoa(p)) |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | for _, p := range unique[1:] { |
| 124 | if p == prev+1 { |
| 125 | prev = p |
| 126 | continue |
| 127 | } |
| 128 | flush(start, prev) |
| 129 | start = p |
| 130 | prev = p |
| 131 | } |
| 132 | flush(start, prev) |
| 133 | |
| 134 | return strings.Join(parts, ", ") |
| 135 | } |
| 136 | |
| 137 | func validatePortBounds(port int) error { |
| 138 | if port < minPort || port > maxPort { |
no outgoing calls