1
0
Fork 0
hivemind/internal/types/web.go

78 lines
1.6 KiB
Go

package types
import (
"encoding/json"
"fmt"
"net/http"
)
// TODO: split this up
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))
}