Files

116 lines
2.4 KiB
Go

package protocol
import (
"encoding/json"
"fmt"
)
type typePeek struct {
V int `json:"v"`
Type string `json:"type"`
}
// Decode 解析一帧 MQTT/应用 JSON,返回具体类型。
func Decode(data []byte) (any, error) {
var peek typePeek
if err := Unmarshal(data, &peek); err != nil {
return nil, badRequest("invalid json")
}
if peek.V != 0 && peek.V != Version {
return nil, badRequest("unsupported version")
}
if peek.Type == "" {
return nil, badRequest("missing type")
}
var out any
switch peek.Type {
case TypeHello:
out = &Hello{}
case TypeResp:
out = &Resp{}
case TypeSend:
out = &Send{}
case TypeMsg:
out = &Msg{}
case TypeAck:
out = &Ack{}
case TypeRecall:
out = &Recall{}
case TypeStatus:
out = &Status{}
case TypeReceipt:
out = &Receipt{}
case TypeReceiptAck:
out = &ReceiptAck{}
case TypeRevoked:
out = &Revoked{}
case TypePresenceGet:
out = &PresenceGet{}
case TypeDirectoryList:
out = &DirectoryList{}
case TypePresenceWatch:
out = &PresenceWatch{}
case TypePresence:
out = &Presence{}
case TypeUnlock:
out = &Unlock{}
case TypeSelfGet:
out = &SelfGet{}
case TypeSelfUpdate:
out = &SelfUpdate{}
case TypeSelfTalkPassword:
out = &SelfTalkPassword{}
case TypeSelfLoginPassword:
out = &SelfLoginPassword{}
case TypeSelfLogout:
out = &SelfLogout{}
case TypeGroupCreate:
out = &GroupCreate{}
case TypeGroupAdd:
out = &GroupAdd{}
case TypeGroupRemove:
out = &GroupRemove{}
case TypeGroupLeave:
out = &GroupLeave{}
case TypeGroupTransfer:
out = &GroupTransfer{}
case TypeGroupRename:
out = &GroupRename{}
case TypeGroupDissolve:
out = &GroupDissolve{}
case TypeGroupList:
out = &GroupList{}
case TypeGroupGet:
out = &GroupGet{}
case TypeGroupEvent:
out = &GroupEvent{}
case TypeFatal:
out = &Fatal{}
default:
return nil, badRequest(fmt.Sprintf("unknown type %q", peek.Type))
}
if err := Unmarshal(data, out); err != nil {
return nil, badRequest("invalid json for type")
}
return out, nil
}
// DecodeRegister 解析注册 HTTP 请求体。
func DecodeRegister(data []byte) (*RegisterRequest, error) {
var req RegisterRequest
if err := Unmarshal(data, &req); err != nil {
return nil, badRequest("invalid json")
}
return &req, nil
}
// MustRaw 将值编码为 json.RawMessage(用于填 Resp.Data)。
func MustRaw(v any) json.RawMessage {
b, err := Marshal(v)
if err != nil {
panic(err)
}
return b
}