2024-07-12 13:30:21 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding"
|
2024-11-09 16:08:39 +00:00
|
|
|
"errors"
|
2024-07-12 13:30:21 +00:00
|
|
|
"fmt"
|
2024-07-22 08:42:25 +00:00
|
|
|
"isle/nebula"
|
2024-11-09 16:08:39 +00:00
|
|
|
"isle/toolkit"
|
2024-12-17 10:33:19 +00:00
|
|
|
"net"
|
2024-07-22 08:42:25 +00:00
|
|
|
"net/netip"
|
2024-12-17 10:33:19 +00:00
|
|
|
"strconv"
|
2024-11-09 16:08:39 +00:00
|
|
|
|
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
2024-07-12 13:30:21 +00:00
|
|
|
)
|
|
|
|
|
2024-07-22 08:42:25 +00:00
|
|
|
type textUnmarshaler[T any] interface {
|
|
|
|
encoding.TextUnmarshaler
|
|
|
|
*T
|
|
|
|
}
|
|
|
|
|
|
|
|
type textUnmarshalerFlag[T encoding.TextMarshaler, P textUnmarshaler[T]] struct {
|
|
|
|
V T
|
2024-07-12 13:30:21 +00:00
|
|
|
}
|
|
|
|
|
2024-07-22 08:42:25 +00:00
|
|
|
func (f *textUnmarshalerFlag[T, P]) Set(v string) error {
|
|
|
|
return P(&(f.V)).UnmarshalText([]byte(v))
|
2024-07-12 13:30:21 +00:00
|
|
|
}
|
|
|
|
|
2024-07-22 08:42:25 +00:00
|
|
|
func (f *textUnmarshalerFlag[T, P]) String() string {
|
|
|
|
b, err := f.V.MarshalText()
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf("calling MarshalText on %#v: %v", f.V, err))
|
|
|
|
}
|
|
|
|
return string(b)
|
2024-07-12 13:30:21 +00:00
|
|
|
}
|
|
|
|
|
2024-07-22 08:42:25 +00:00
|
|
|
func (f *textUnmarshalerFlag[T, P]) Type() string { return "string" }
|
|
|
|
|
|
|
|
type (
|
|
|
|
hostNameFlag = textUnmarshalerFlag[nebula.HostName, *nebula.HostName]
|
|
|
|
ipNetFlag = textUnmarshalerFlag[nebula.IPNet, *nebula.IPNet]
|
|
|
|
ipFlag = textUnmarshalerFlag[netip.Addr, *netip.Addr]
|
|
|
|
)
|
2024-11-09 16:08:39 +00:00
|
|
|
|
2024-12-17 10:33:19 +00:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
type (
|
|
|
|
addrFlagStr string
|
|
|
|
addrFlag = textUnmarshalerFlag[addrFlagStr, *addrFlagStr]
|
|
|
|
)
|
|
|
|
|
|
|
|
func (f addrFlagStr) MarshalText() ([]byte, error) {
|
|
|
|
return []byte(f), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *addrFlagStr) UnmarshalText(b []byte) error {
|
|
|
|
str := string(b)
|
|
|
|
|
|
|
|
_, portStr, err := net.SplitHostPort(str)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := strconv.ParseUint(portStr, 10, 16); err != nil {
|
|
|
|
return fmt.Errorf("invalid port %q", portStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
*f = addrFlagStr(str)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2024-11-09 16:08:39 +00:00
|
|
|
type logLevelFlag struct {
|
|
|
|
mlog.Level
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *logLevelFlag) Set(v string) error {
|
|
|
|
f.Level = toolkit.LogLevelFromString(v)
|
|
|
|
if f.Level == nil {
|
|
|
|
return errors.New("not a valid log level")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *logLevelFlag) String() string {
|
|
|
|
if f.Level == nil {
|
|
|
|
return "UNKNOWN"
|
|
|
|
}
|
|
|
|
return f.Level.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *logLevelFlag) Type() string { return "string" }
|