diff --git a/README.md b/README.md index 969ea1a..f37419d 100644 --- a/README.md +++ b/README.md @@ -106,10 +106,19 @@ Here's a compact overview: | [Regexps](https://godoc.org/github.com/sgreben/flagvar#Regexps) | [a-z]+ | []*regexp.Regexp | | [Strings](https://godoc.org/github.com/sgreben/flagvar#Strings) | "xyxy" | []string | | [StringSet](https://godoc.org/github.com/sgreben/flagvar#StringSet) | "xyxy" | []string | +| [TCPAddr](https://godoc.org/github.com/sgreben/flagvar#TCPAddr) | 127.0.0.1:10 | net.TCPAddr | +| [TCPAddrs](https://godoc.org/github.com/sgreben/flagvar#TCPAddrs) | 127.0.0.1:10 | []net.TCPAddr | +| [TCPAddrsCSV](https://godoc.org/github.com/sgreben/flagvar#TCPAddrsCSV) | 127.0.0.1:10,:123 | []net.TCPAddr | | [Template](https://godoc.org/github.com/sgreben/flagvar#Template) | "{{.Size}}" | *template.Template | | [Templates](https://godoc.org/github.com/sgreben/flagvar#Templates) | "{{.Size}}" | []*template.Template | | [Time](https://godoc.org/github.com/sgreben/flagvar#Time) | "10:30 AM" | time.Time | | [Times](https://godoc.org/github.com/sgreben/flagvar#Times) | "10:30 AM" | []time.Time | +| [UDPAddr](https://godoc.org/github.com/sgreben/flagvar#UDPAddr) | 127.0.0.1:10 | net.UDPAddr | +| [UDPAddrs](https://godoc.org/github.com/sgreben/flagvar#UDPAddrs) | 127.0.0.1:10 | []net.UDPAddr | +| [UDPAddrsCSV](https://godoc.org/github.com/sgreben/flagvar#UDPAddrsCSV) | 127.0.0.1:10,:123 | []net.UDPAddr | +| [UnixAddr](https://godoc.org/github.com/sgreben/flagvar#UnixAddr) | /example.sock | net.UnixAddr | +| [UnixAddrs](https://godoc.org/github.com/sgreben/flagvar#UnixAddrs) | /example.sock | []net.UnixAddr | +| [UnixAddrsCSV](https://godoc.org/github.com/sgreben/flagvar#UnixAddrsCSV) | /example.sock,/other.sock | []net.UnixAddr | | [URL](https://godoc.org/github.com/sgreben/flagvar#URL) | https://github.com | *url.URL | | [URLs](https://godoc.org/github.com/sgreben/flagvar#URLs) | https://github.com | []*url.URL | | [Wrap](https://godoc.org/github.com/sgreben/flagvar#Wrap) | | | diff --git a/tcp_addr.go b/tcp_addr.go new file mode 100644 index 0000000..859b2ea --- /dev/null +++ b/tcp_addr.go @@ -0,0 +1,107 @@ +package flagvar + +import ( + "strings" + + "net" +) + +// TCPAddr is a `flag.Value` for TCP addresses. +// The `Network` field is used if set, otherwise "tcp". +type TCPAddr struct { + Network string + + Value *net.TCPAddr + Text string +} + +// Set is flag.Value.Set +func (fv *TCPAddr) Set(v string) error { + network := "tcp" + if fv.Network != "" { + network = fv.Network + } + tcpAddr, err := net.ResolveTCPAddr(network, v) + if err != nil { + return err + } + fv.Text = v + fv.Value = tcpAddr + return nil +} + +func (fv *TCPAddr) String() string { + return fv.Text +} + +// TCPAddrs is a `flag.Value` for TCPAddr addresses. +// The `Network` field is used if set, otherwise "tcp". +type TCPAddrs struct { + Network string + + Values []*net.TCPAddr + Texts []string +} + +// Set is flag.Value.Set +func (fv *TCPAddrs) Set(v string) error { + network := "tcp" + if fv.Network != "" { + network = fv.Network + } + tcpAddr, err := net.ResolveTCPAddr(network, v) + if err != nil { + return err + } + fv.Texts = append(fv.Texts, v) + fv.Values = append(fv.Values, tcpAddr) + return nil +} + +func (fv *TCPAddrs) String() string { + return strings.Join(fv.Texts, ",") +} + +// TCPAddrsCSV is a `flag.Value` for TCPAddr addresses. +// The `Network` field is used if set, otherwise "tcp". +// If `Accumulate` is set, the values of all instances of the flag are accumulated. +// The `Separator` field is used instead of the comma when set. +type TCPAddrsCSV struct { + Network string + Separator string + Accumulate bool + + Values []*net.TCPAddr + Texts []string +} + +// Set is flag.Value.Set +func (fv *TCPAddrsCSV) Set(v string) error { + network := "tcp" + if fv.Network != "" { + network = fv.Network + } + separator := fv.Separator + if separator == "" { + separator = "," + } + if !fv.Accumulate { + fv.Values = fv.Values[:0] + fv.Texts = fv.Texts[:0] + } + parts := strings.Split(v, separator) + for _, part := range parts { + part = strings.TrimSpace(part) + tcpAddr, err := net.ResolveTCPAddr(network, part) + if err != nil { + return err + } + fv.Texts = append(fv.Texts, part) + fv.Values = append(fv.Values, tcpAddr) + } + return nil +} + +func (fv *TCPAddrsCSV) String() string { + return strings.Join(fv.Texts, ",") +} diff --git a/tcp_addr_test.go b/tcp_addr_test.go new file mode 100644 index 0000000..c528dd3 --- /dev/null +++ b/tcp_addr_test.go @@ -0,0 +1,170 @@ +package flagvar_test + +import ( + "flag" + "net" + "reflect" + "testing" + + "github.com/sgreben/flagvar" +) + +func TestTCPAddr(t *testing.T) { + fv := flagvar.TCPAddr{} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addr", "") + + err := fs.Parse([]string{"-tcp-addr", "127.0.0.1:123"}) + if err != nil { + t.Fail() + } + addr, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:123") + if !reflect.DeepEqual(fv.Value, addr) { + t.Fail() + } +} + +func TestTCPAddrNetwork(t *testing.T) { + fv := flagvar.TCPAddr{Network: "tcp4"} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addr", "") + + err := fs.Parse([]string{"-tcp-addr", "127.0.0.1:123"}) + if err != nil { + t.Fail() + } + addr, _ := net.ResolveTCPAddr("tcp4", "127.0.0.1:123") + if !reflect.DeepEqual(fv.Value, addr) { + t.Fail() + } +} + +func TestTCPAddrFail(t *testing.T) { + fv := flagvar.TCPAddr{} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addr", "") + + err := fs.Parse([]string{"-tcp-addr", "999.999.999.999:1"}) + if err == nil { + t.Fail() + } +} + +func TestTCPAddrs(t *testing.T) { + fv := flagvar.TCPAddrs{} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addr", "") + + err := fs.Parse([]string{"-tcp-addr", "127.0.0.1:123", "-tcp-addr", ":80"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:123") + addr2, _ := net.ResolveTCPAddr("tcp", ":80") + if !reflect.DeepEqual(fv.Values, []*net.TCPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestTCPAddrsNetwork(t *testing.T) { + fv := flagvar.TCPAddrs{Network: "tcp4"} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addr", "") + + err := fs.Parse([]string{"-tcp-addr", "127.0.0.1:123", "-tcp-addr", ":80"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveTCPAddr("tcp4", "127.0.0.1:123") + addr2, _ := net.ResolveTCPAddr("tcp4", ":80") + if !reflect.DeepEqual(fv.Values, []*net.TCPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestTCPAddrsFail(t *testing.T) { + fv := flagvar.TCPAddrs{} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addr", "") + + err := fs.Parse([]string{"-tcp-addr", "[a-"}) + if err == nil { + t.Fail() + } +} + +func TestTCPAddrsCSV(t *testing.T) { + fv := flagvar.TCPAddrsCSV{} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addrs-csv", "") + + err := fs.Parse([]string{"-tcp-addrs-csv", "127.0.0.1:123,10.10.1.2:13"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:123") + addr2, _ := net.ResolveTCPAddr("tcp", "10.10.1.2:13") + if !reflect.DeepEqual(fv.Values, []*net.TCPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestTCPAddrsCSVNetwork(t *testing.T) { + fv := flagvar.TCPAddrsCSV{Network: "tcp4"} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addrs-csv", "") + + err := fs.Parse([]string{"-tcp-addrs-csv", "127.0.0.1:123,10.10.1.2:13"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveTCPAddr("tcp4", "127.0.0.1:123") + addr2, _ := net.ResolveTCPAddr("tcp4", "10.10.1.2:13") + if !reflect.DeepEqual(fv.Values, []*net.TCPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestTCPAddrsCSVSeparator(t *testing.T) { + fv := flagvar.TCPAddrsCSV{Separator: ";"} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addrs-csv", "") + + err := fs.Parse([]string{"-tcp-addrs-csv", "127.0.0.1:123;:32"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:123") + addr2, _ := net.ResolveTCPAddr("tcp", ":32") + if !reflect.DeepEqual(fv.Values, []*net.TCPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestTCPAddrsCSVAccumulate(t *testing.T) { + fv := flagvar.TCPAddrsCSV{Accumulate: true} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addrs-csv", "") + + err := fs.Parse([]string{"-tcp-addrs-csv", "127.0.0.1:123,10.10.1.2:432", "-tcp-addrs-csv", "10.10.1.2:432"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveTCPAddr("tcp", "127.0.0.1:123") + addr2, _ := net.ResolveTCPAddr("tcp", "10.10.1.2:432") + addr3, _ := net.ResolveTCPAddr("tcp", "10.10.1.2:432") + if !reflect.DeepEqual(fv.Values, []*net.TCPAddr{addr1, addr2, addr3}) { + t.Fail() + } +} + +func TestTCPAddrsCSVFail(t *testing.T) { + fv := flagvar.TCPAddrsCSV{} + var fs flag.FlagSet + fs.Var(&fv, "tcp-addrs-csv", "") + + err := fs.Parse([]string{"-tcp-addrs-csv", "999.999.999.1:1"}) + if err == nil { + t.Fail() + } +} diff --git a/udp_addr.go b/udp_addr.go new file mode 100644 index 0000000..11c9098 --- /dev/null +++ b/udp_addr.go @@ -0,0 +1,107 @@ +package flagvar + +import ( + "strings" + + "net" +) + +// UDPAddr is a `flag.Value` for UDP addresses. +// The `Network` field is used if set, otherwise "udp". +type UDPAddr struct { + Network string + + Value *net.UDPAddr + Text string +} + +// Set is flag.Value.Set +func (fv *UDPAddr) Set(v string) error { + network := "udp" + if fv.Network != "" { + network = fv.Network + } + udpAddr, err := net.ResolveUDPAddr(network, v) + if err != nil { + return err + } + fv.Text = v + fv.Value = udpAddr + return nil +} + +func (fv *UDPAddr) String() string { + return fv.Text +} + +// UDPAddrs is a `flag.Value` for UDPAddr addresses. +// The `Network` field is used if set, otherwise "udp". +type UDPAddrs struct { + Network string + + Values []*net.UDPAddr + Texts []string +} + +// Set is flag.Value.Set +func (fv *UDPAddrs) Set(v string) error { + network := "udp" + if fv.Network != "" { + network = fv.Network + } + udpAddr, err := net.ResolveUDPAddr(network, v) + if err != nil { + return err + } + fv.Texts = append(fv.Texts, v) + fv.Values = append(fv.Values, udpAddr) + return nil +} + +func (fv *UDPAddrs) String() string { + return strings.Join(fv.Texts, ",") +} + +// UDPAddrsCSV is a `flag.Value` for UDPAddr addresses. +// The `Network` field is used if set, otherwise "udp". +// If `Accumulate` is set, the values of all instances of the flag are accumulated. +// The `Separator` field is used instead of the comma when set. +type UDPAddrsCSV struct { + Network string + Separator string + Accumulate bool + + Values []*net.UDPAddr + Texts []string +} + +// Set is flag.Value.Set +func (fv *UDPAddrsCSV) Set(v string) error { + network := "udp" + if fv.Network != "" { + network = fv.Network + } + separator := fv.Separator + if separator == "" { + separator = "," + } + if !fv.Accumulate { + fv.Values = fv.Values[:0] + fv.Texts = fv.Texts[:0] + } + parts := strings.Split(v, separator) + for _, part := range parts { + part = strings.TrimSpace(part) + udpAddr, err := net.ResolveUDPAddr(network, part) + if err != nil { + return err + } + fv.Texts = append(fv.Texts, part) + fv.Values = append(fv.Values, udpAddr) + } + return nil +} + +func (fv *UDPAddrsCSV) String() string { + return strings.Join(fv.Texts, ",") +} diff --git a/udp_addr_test.go b/udp_addr_test.go new file mode 100644 index 0000000..31a7e8f --- /dev/null +++ b/udp_addr_test.go @@ -0,0 +1,170 @@ +package flagvar_test + +import ( + "flag" + "net" + "reflect" + "testing" + + "github.com/sgreben/flagvar" +) + +func TestUDPAddr(t *testing.T) { + fv := flagvar.UDPAddr{} + var fs flag.FlagSet + fs.Var(&fv, "udp-addr", "") + + err := fs.Parse([]string{"-udp-addr", "127.0.0.1:123"}) + if err != nil { + t.Fail() + } + addr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:123") + if !reflect.DeepEqual(fv.Value, addr) { + t.Fail() + } +} + +func TestUDPAddrNetwork(t *testing.T) { + fv := flagvar.UDPAddr{Network: "udp4"} + var fs flag.FlagSet + fs.Var(&fv, "udp-addr", "") + + err := fs.Parse([]string{"-udp-addr", "127.0.0.1:123"}) + if err != nil { + t.Fail() + } + addr, _ := net.ResolveUDPAddr("udp4", "127.0.0.1:123") + if !reflect.DeepEqual(fv.Value, addr) { + t.Fail() + } +} + +func TestUDPAddrFail(t *testing.T) { + fv := flagvar.UDPAddr{} + var fs flag.FlagSet + fs.Var(&fv, "udp-addr", "") + + err := fs.Parse([]string{"-udp-addr", "999.999.999.999:1"}) + if err == nil { + t.Fail() + } +} + +func TestUDPAddrs(t *testing.T) { + fv := flagvar.UDPAddrs{} + var fs flag.FlagSet + fs.Var(&fv, "udp-addr", "") + + err := fs.Parse([]string{"-udp-addr", "127.0.0.1:123", "-udp-addr", ":80"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUDPAddr("udp", "127.0.0.1:123") + addr2, _ := net.ResolveUDPAddr("udp", ":80") + if !reflect.DeepEqual(fv.Values, []*net.UDPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUDPAddrsNetwork(t *testing.T) { + fv := flagvar.UDPAddrs{Network: "udp4"} + var fs flag.FlagSet + fs.Var(&fv, "udp-addr", "") + + err := fs.Parse([]string{"-udp-addr", "127.0.0.1:123", "-udp-addr", ":80"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUDPAddr("udp4", "127.0.0.1:123") + addr2, _ := net.ResolveUDPAddr("udp4", ":80") + if !reflect.DeepEqual(fv.Values, []*net.UDPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUDPAddrsFail(t *testing.T) { + fv := flagvar.UDPAddrs{} + var fs flag.FlagSet + fs.Var(&fv, "udp-addr", "") + + err := fs.Parse([]string{"-udp-addr", "[a-"}) + if err == nil { + t.Fail() + } +} + +func TestUDPAddrsCSV(t *testing.T) { + fv := flagvar.UDPAddrsCSV{} + var fs flag.FlagSet + fs.Var(&fv, "udp-addrs-csv", "") + + err := fs.Parse([]string{"-udp-addrs-csv", "127.0.0.1:123,10.10.1.2:13"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUDPAddr("udp", "127.0.0.1:123") + addr2, _ := net.ResolveUDPAddr("udp", "10.10.1.2:13") + if !reflect.DeepEqual(fv.Values, []*net.UDPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUDPAddrsCSVNetwork(t *testing.T) { + fv := flagvar.UDPAddrsCSV{Network: "udp4"} + var fs flag.FlagSet + fs.Var(&fv, "udp-addrs-csv", "") + + err := fs.Parse([]string{"-udp-addrs-csv", "127.0.0.1:123,10.10.1.2:13"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUDPAddr("udp4", "127.0.0.1:123") + addr2, _ := net.ResolveUDPAddr("udp4", "10.10.1.2:13") + if !reflect.DeepEqual(fv.Values, []*net.UDPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUDPAddrsCSVSeparator(t *testing.T) { + fv := flagvar.UDPAddrsCSV{Separator: ";"} + var fs flag.FlagSet + fs.Var(&fv, "udp-addrs-csv", "") + + err := fs.Parse([]string{"-udp-addrs-csv", "127.0.0.1:123;:32"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUDPAddr("udp", "127.0.0.1:123") + addr2, _ := net.ResolveUDPAddr("udp", ":32") + if !reflect.DeepEqual(fv.Values, []*net.UDPAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUDPAddrsCSVAccumulate(t *testing.T) { + fv := flagvar.UDPAddrsCSV{Accumulate: true} + var fs flag.FlagSet + fs.Var(&fv, "udp-addrs-csv", "") + + err := fs.Parse([]string{"-udp-addrs-csv", "127.0.0.1:123,10.10.1.2:432", "-udp-addrs-csv", "10.10.1.2:432"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUDPAddr("udp", "127.0.0.1:123") + addr2, _ := net.ResolveUDPAddr("udp", "10.10.1.2:432") + addr3, _ := net.ResolveUDPAddr("udp", "10.10.1.2:432") + if !reflect.DeepEqual(fv.Values, []*net.UDPAddr{addr1, addr2, addr3}) { + t.Fail() + } +} + +func TestUDPAddrsCSVFail(t *testing.T) { + fv := flagvar.UDPAddrsCSV{} + var fs flag.FlagSet + fs.Var(&fv, "udp-addrs-csv", "") + + err := fs.Parse([]string{"-udp-addrs-csv", "999.999.999.1:1"}) + if err == nil { + t.Fail() + } +} diff --git a/unix_addr.go b/unix_addr.go new file mode 100644 index 0000000..5a49df3 --- /dev/null +++ b/unix_addr.go @@ -0,0 +1,107 @@ +package flagvar + +import ( + "strings" + + "net" +) + +// UnixAddr is a `flag.Value` for Unix addresses. +// The `Network` field is used if set, otherwise "unix". +type UnixAddr struct { + Network string + + Value *net.UnixAddr + Text string +} + +// Set is flag.Value.Set +func (fv *UnixAddr) Set(v string) error { + network := "unix" + if fv.Network != "" { + network = fv.Network + } + unixAddr, err := net.ResolveUnixAddr(network, v) + if err != nil { + return err + } + fv.Text = v + fv.Value = unixAddr + return nil +} + +func (fv *UnixAddr) String() string { + return fv.Text +} + +// UnixAddrs is a `flag.Value` for UnixAddr addresses. +// The `Network` field is used if set, otherwise "unix". +type UnixAddrs struct { + Network string + + Values []*net.UnixAddr + Texts []string +} + +// Set is flag.Value.Set +func (fv *UnixAddrs) Set(v string) error { + network := "unix" + if fv.Network != "" { + network = fv.Network + } + unixAddr, err := net.ResolveUnixAddr(network, v) + if err != nil { + return err + } + fv.Texts = append(fv.Texts, v) + fv.Values = append(fv.Values, unixAddr) + return nil +} + +func (fv *UnixAddrs) String() string { + return strings.Join(fv.Texts, ",") +} + +// UnixAddrsCSV is a `flag.Value` for UnixAddr addresses. +// The `Network` field is used if set, otherwise "unix". +// If `Accumulate` is set, the values of all instances of the flag are accumulated. +// The `Separator` field is used instead of the comma when set. +type UnixAddrsCSV struct { + Network string + Separator string + Accumulate bool + + Values []*net.UnixAddr + Texts []string +} + +// Set is flag.Value.Set +func (fv *UnixAddrsCSV) Set(v string) error { + network := "unix" + if fv.Network != "" { + network = fv.Network + } + separator := fv.Separator + if separator == "" { + separator = "," + } + if !fv.Accumulate { + fv.Values = fv.Values[:0] + fv.Texts = fv.Texts[:0] + } + parts := strings.Split(v, separator) + for _, part := range parts { + part = strings.TrimSpace(part) + unixAddr, err := net.ResolveUnixAddr(network, part) + if err != nil { + return err + } + fv.Texts = append(fv.Texts, part) + fv.Values = append(fv.Values, unixAddr) + } + return nil +} + +func (fv *UnixAddrsCSV) String() string { + return strings.Join(fv.Texts, ",") +} diff --git a/unix_addr_test.go b/unix_addr_test.go new file mode 100644 index 0000000..93e955b --- /dev/null +++ b/unix_addr_test.go @@ -0,0 +1,170 @@ +package flagvar_test + +import ( + "flag" + "net" + "reflect" + "testing" + + "github.com/sgreben/flagvar" +) + +func TestUnixAddr(t *testing.T) { + fv := flagvar.UnixAddr{} + var fs flag.FlagSet + fs.Var(&fv, "unix-addr", "") + + err := fs.Parse([]string{"-unix-addr", "/example.sock"}) + if err != nil { + t.Fail() + } + addr, _ := net.ResolveUnixAddr("unix", "/example.sock") + if !reflect.DeepEqual(fv.Value, addr) { + t.Fail() + } +} + +func TestUnixAddrNetwork(t *testing.T) { + fv := flagvar.UnixAddr{Network: "unixpacket"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addr", "") + + err := fs.Parse([]string{"-unix-addr", "/example.sock"}) + if err != nil { + t.Fail() + } + addr, _ := net.ResolveUnixAddr("unixpacket", "/example.sock") + if !reflect.DeepEqual(fv.Value, addr) { + t.Fail() + } +} + +func TestUnixAddrFail(t *testing.T) { + fv := flagvar.UnixAddr{Network: "not-unix"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addr", "") + + err := fs.Parse([]string{"-unix-addr", "/example.sock"}) + if err == nil { + t.Fail() + } +} + +func TestUnixAddrs(t *testing.T) { + fv := flagvar.UnixAddrs{} + var fs flag.FlagSet + fs.Var(&fv, "unix-addr", "") + + err := fs.Parse([]string{"-unix-addr", "/example.sock", "-unix-addr", "/other.sock"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUnixAddr("unix", "/example.sock") + addr2, _ := net.ResolveUnixAddr("unix", "/other.sock") + if !reflect.DeepEqual(fv.Values, []*net.UnixAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUnixAddrsNetwork(t *testing.T) { + fv := flagvar.UnixAddrs{Network: "unixpacket"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addr", "") + + err := fs.Parse([]string{"-unix-addr", "/example.sock", "-unix-addr", "/other.sock"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUnixAddr("unixpacket", "/example.sock") + addr2, _ := net.ResolveUnixAddr("unixpacket", "/other.sock") + if !reflect.DeepEqual(fv.Values, []*net.UnixAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUnixAddrsFail(t *testing.T) { + fv := flagvar.UnixAddrs{Network: "not-unix"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addr", "") + + err := fs.Parse([]string{"-unix-addr", "/example.sock"}) + if err == nil { + t.Fail() + } +} + +func TestUnixAddrsCSV(t *testing.T) { + fv := flagvar.UnixAddrsCSV{} + var fs flag.FlagSet + fs.Var(&fv, "unix-addrs-csv", "") + + err := fs.Parse([]string{"-unix-addrs-csv", "/example.sock,/other.sock"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUnixAddr("unix", "/example.sock") + addr2, _ := net.ResolveUnixAddr("unix", "/other.sock") + if !reflect.DeepEqual(fv.Values, []*net.UnixAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUnixAddrsCSVNetwork(t *testing.T) { + fv := flagvar.UnixAddrsCSV{Network: "unixpacket"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addrs-csv", "") + + err := fs.Parse([]string{"-unix-addrs-csv", "/example.sock,/other.sock"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUnixAddr("unixpacket", "/example.sock") + addr2, _ := net.ResolveUnixAddr("unixpacket", "/other.sock") + if !reflect.DeepEqual(fv.Values, []*net.UnixAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUnixAddrsCSVSeparator(t *testing.T) { + fv := flagvar.UnixAddrsCSV{Separator: ";"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addrs-csv", "") + + err := fs.Parse([]string{"-unix-addrs-csv", "/example.sock;:32"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUnixAddr("unix", "/example.sock") + addr2, _ := net.ResolveUnixAddr("unix", ":32") + if !reflect.DeepEqual(fv.Values, []*net.UnixAddr{addr1, addr2}) { + t.Fail() + } +} + +func TestUnixAddrsCSVAccumulate(t *testing.T) { + fv := flagvar.UnixAddrsCSV{Accumulate: true} + var fs flag.FlagSet + fs.Var(&fv, "unix-addrs-csv", "") + + err := fs.Parse([]string{"-unix-addrs-csv", "/example.sock,/other.sock", "-unix-addrs-csv", "/other.sock"}) + if err != nil { + t.Fail() + } + addr1, _ := net.ResolveUnixAddr("unix", "/example.sock") + addr2, _ := net.ResolveUnixAddr("unix", "/other.sock") + addr3, _ := net.ResolveUnixAddr("unix", "/other.sock") + if !reflect.DeepEqual(fv.Values, []*net.UnixAddr{addr1, addr2, addr3}) { + t.Fail() + } +} + +func TestUnixAddrsCSVFail(t *testing.T) { + fv := flagvar.UnixAddrsCSV{Network: "not-unix"} + var fs flag.FlagSet + fs.Var(&fv, "unix-addrs-csv", "") + + err := fs.Parse([]string{"-unix-addrs-csv", "/example.sock"}) + if err == nil { + t.Fail() + } +}