Files
谢宇宁andClaude Opus 5.5 0fbdba5ccf Initial commit
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 11:47:47 +07:00

70 lines
1.4 KiB
Go

package playletser
import (
"bytes"
"encoding/json"
"strings"
)
// UnmarshalJSON 兼容上游 data 为对象、null、空字符串,或二次 JSON 编码的字符串。
func (e *APIEnvelope[T]) UnmarshalJSON(raw []byte) error {
if e == nil {
return nil
}
raw = bytes.TrimSpace(raw)
if len(raw) == 0 || bytes.Equal(raw, []byte("null")) {
return nil
}
var aux struct {
Code int `json:"code"`
Msg string `json:"msg"`
Tip string `json:"tip"`
Data json.RawMessage `json:"data"`
}
if err := json.Unmarshal(raw, &aux); err != nil {
return err
}
e.Code = aux.Code
e.Msg = aux.Msg
e.Tip = aux.Tip
data, err := unmarshalEnvelopeData[T](aux.Data)
if err != nil {
return err
}
e.Data = data
return nil
}
func unmarshalEnvelopeData[T any](raw json.RawMessage) (T, error) {
var zero T
raw = bytes.TrimSpace(raw)
if len(raw) == 0 || bytes.Equal(raw, []byte("null")) {
return zero, nil
}
if raw[0] == '"' {
var s string
if err := json.Unmarshal(raw, &s); err != nil {
return zero, err
}
s = strings.TrimSpace(s)
if s == "" {
return zero, nil
}
inner := bytes.TrimSpace([]byte(s))
if len(inner) == 0 {
return zero, nil
}
if inner[0] != '{' && inner[0] != '[' {
return zero, nil
}
if err := json.Unmarshal(inner, &zero); err != nil {
return zero, err
}
return zero, nil
}
if err := json.Unmarshal(raw, &zero); err != nil {
return zero, err
}
return zero, nil
}