Files
notarius/internal/modules/dnd/extract/combatturns/model.go

106 lines
3.1 KiB
Go

package combatturns
import (
"bytes"
"encoding/json"
"fmt"
)
type extractionResponse struct {
CombatTurns []combatTurnResponse `json:"combat_turns"`
}
type combatTurnResponse struct {
Actor string `json:"actor"`
TurnKind string `json:"turn_kind"`
Round *int `json:"round"`
Actions []combatActionResponse `json:"actions"`
Summary string `json:"summary"`
SourceRefs []combatSourceRefResponse `json:"source_refs"`
}
type combatActionResponse struct {
Category string `json:"category"`
Declaration string `json:"declaration"`
Targets []string `json:"targets"`
Resolution *string `json:"resolution"`
}
type combatSourceRefResponse struct {
StartUnitID int `json:"start_unit_id"`
EndUnitID int `json:"end_unit_id"`
}
func (response *combatTurnResponse) UnmarshalJSON(content []byte) error {
type responseWire struct {
Actor string `json:"actor"`
TurnKind string `json:"turn_kind"`
Round json.RawMessage `json:"round"`
Actions []combatActionResponse `json:"actions"`
Summary string `json:"summary"`
SourceRefs []combatSourceRefResponse `json:"source_refs"`
}
var wire responseWire
if err := json.Unmarshal(content, &wire); err != nil {
return err
}
round, err := decodeRequiredNullableInt(wire.Round, "round")
if err != nil {
return err
}
*response = combatTurnResponse{
Actor: wire.Actor, TurnKind: wire.TurnKind, Round: round, Actions: wire.Actions,
Summary: wire.Summary, SourceRefs: wire.SourceRefs,
}
return nil
}
func (response *combatActionResponse) UnmarshalJSON(content []byte) error {
type responseWire struct {
Category string `json:"category"`
Declaration string `json:"declaration"`
Targets []string `json:"targets"`
Resolution json.RawMessage `json:"resolution"`
}
var wire responseWire
if err := json.Unmarshal(content, &wire); err != nil {
return err
}
resolution, err := decodeRequiredNullableString(wire.Resolution, "resolution")
if err != nil {
return err
}
*response = combatActionResponse{
Category: wire.Category, Declaration: wire.Declaration, Targets: wire.Targets, Resolution: resolution,
}
return nil
}
func decodeRequiredNullableInt(raw json.RawMessage, field string) (*int, error) {
if len(raw) == 0 {
return nil, fmt.Errorf("%s must be present", field)
}
if bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
return nil, nil
}
var value int
if err := json.Unmarshal(raw, &value); err != nil {
return nil, fmt.Errorf("%s must be an integer or null: %w", field, err)
}
return &value, nil
}
func decodeRequiredNullableString(raw json.RawMessage, field string) (*string, error) {
if len(raw) == 0 {
return nil, fmt.Errorf("%s must be present", field)
}
if bytes.Equal(bytes.TrimSpace(raw), []byte("null")) {
return nil, nil
}
var value string
if err := json.Unmarshal(raw, &value); err != nil {
return nil, fmt.Errorf("%s must be a string or null: %w", field, err)
}
return &value, nil
}