package types import ( "encoding/json" "fmt" "net/http" ) type Path string func (p Path) String() string { return string(p) } const ( PathMasterJoin Path = "/master/join" PathMasterLeave Path = "/master/leave" PathMasterKeepalive Path = "/master/keepalive" PathNodeHealthcheck Path = "/node/healthcheck" PathNodeJoin Path = "/node/join" PathNodeLeave Path = "/node/leave" PathDnsCallback Path = "/dns/callback" PathHostCallback Path = "/host/callback" PathHostDns Path = "/host/dns" PathHostNs Path = "/host/ns" ) type Response[T any] struct { Ok bool `json:"ok"` Data T `json:"data,omitempty"` Err string `json:"err,omitempty"` } type Route interface { Path() string Handle([]byte) (any, error) } type endpoint struct { path string handler func([]byte) (any, error) } func (e endpoint) Path() string { return e.path } func (e endpoint) Handle(v []byte) (any, error) { return e.handler(v) } func PostEndpoint[T any, V any](path Path, handler func(T) (V, error)) Route { return endpoint{ path: "POST " + path.String(), handler: func(a []byte) (any, error) { var r T if err := json.Unmarshal(a, &r); err != nil { return nil, fmt.Errorf("unable to unmarshal json: %w", err) } return handler(r) }, } } func GetEndpoint[T any](path Path, handler func() (T, error)) Route { return endpoint{ path: "GET " + path.String(), handler: func(a []byte) (any, error) { return handler() }, } } type Registrator interface { Register(endpoint Route) RegisterRaw(method string, pattern string, handler func(http.ResponseWriter, *http.Request)) }