Files
notarius/internal/modules/dnd/codec/candidatejson/candidate_json.go

39 lines
1.1 KiB
Go

// Package candidatejson provides strict JSON mechanics for D&D artifact
// candidates before artifact-specific validation.
package candidatejson
import (
"bytes"
"encoding/json"
"fmt"
"io"
)
// EncodeCandidate encodes a typed candidate with an artifact-specific error
// label.
func EncodeCandidate[T any](label string, value T) ([]byte, error) {
content, err := json.Marshal(value)
if err != nil {
return nil, fmt.Errorf("encode %s: %w", label, err)
}
return content, nil
}
// DecodeCandidate decodes exactly one typed JSON value while rejecting unknown
// fields and trailing values with an artifact-specific error label.
func DecodeCandidate[T any](label string, content []byte) (T, error) {
decoder := json.NewDecoder(bytes.NewReader(content))
decoder.DisallowUnknownFields()
var value T
if err := decoder.Decode(&value); err != nil {
var zero T
return zero, fmt.Errorf("decode %s: %w", label, err)
}
var trailing any
if err := decoder.Decode(&trailing); err != io.EOF {
var zero T
return zero, fmt.Errorf("decode %s: multiple JSON values", label)
}
return value, nil
}