106 lines
3.1 KiB
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
|
|
}
|