Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
70 lines
1.4 KiB
Go
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
|
|
}
|