diff --git a/internal/chronicle/core/domain/game_character.go b/internal/chronicle/core/domain/game_character.go index 72f0576..a9fdd11 100644 --- a/internal/chronicle/core/domain/game_character.go +++ b/internal/chronicle/core/domain/game_character.go @@ -1,21 +1,21 @@ package domain import ( - "encoding/json" "fmt" "os" + "github.com/goccy/go-json" "github.com/kaptinlin/jsonschema" ) // This should probably be generic, need to // test this against the schema compiler though. // Maybe after it is valid, we can marshall to a strict type -type GameCharacter struct { - Data interface{} +type GameCharacter[D interface{}] struct { + Data D } -func (g GameCharacter) Validate() (bool, error) { +func (g GameCharacter[D]) Validate() (bool, error) { // For now just read on load (for testing purposes), we can deal with caching this later var vtmV5CharacterSchema, err = os.ReadFile("./game/vtm_v5_character_schema.json") if err != nil { @@ -28,9 +28,28 @@ func (g GameCharacter) Validate() (bool, error) { return false, err } - result := schema.Validate(g.Data) + // Need to figure this out but I believe the validator + // requires it to be a map of interfaces. + // For now we are going to marshall and unmarshall back into + // a generic interface of maps so we can validate the schema + // Hide it all here + dataAsByte, err := json.Marshal(g.Data) + if err != nil { + return false, err + } + + var dataAsInterface interface{} + err = json.Unmarshal(dataAsByte, &dataAsInterface) + if err != nil { + return false, err + } + + result := schema.Validate(dataAsInterface) if !result.IsValid() { - details, _ := json.MarshalIndent(result.ToList(), "", " ") + details, err := json.MarshalIndent(result.ToList(), "", " ") + if err != nil { + return false, err + } fmt.Println(string(details)) return false, nil } @@ -39,5 +58,18 @@ func (g GameCharacter) Validate() (bool, error) { } type VtmGameCharacter struct { - Name string `json:"name"` + Name string `json:"name"` + Disciplines []Discipline `json:"disciplines"` +} + +type Discipline struct { + Name string `json:"name"` + Level int `json:"level"` + Powers []Power `json:"powers"` +} + +type Power struct { + Name string `json:"name"` + Level int `json:"level"` + Description string `json:"description,omitempty"` } diff --git a/internal/chronicle/core/domain/game_character_test.go b/internal/chronicle/core/domain/game_character_test.go index 4fa2e16..699ecca 100644 --- a/internal/chronicle/core/domain/game_character_test.go +++ b/internal/chronicle/core/domain/game_character_test.go @@ -1,10 +1,10 @@ package domain_test import ( - "encoding/json" "testing" "github.com/SomethingSexy/chronicle/internal/chronicle/core/domain" + "github.com/goccy/go-json" ) func TestGameCharacter_Validate_Valid(t *testing.T) { @@ -16,7 +16,7 @@ func TestGameCharacter_Validate_Valid(t *testing.T) { t.Fatalf("Failed to unmarshal test cases: %v", err) } - gameCharacter := domain.GameCharacter{ + gameCharacter := domain.GameCharacter[any]{ Data: data, } @@ -32,45 +32,19 @@ func TestGameCharacter_Validate_Valid(t *testing.T) { } func TestGameCharacter_Validate_Disciplines_Valid(t *testing.T) { - // { - // "name": "Protean", - // "level": 3, - // "powers": [ - // { - // "name": "Eyes of the Beast", - // "level": 1, - // "description": "See perfectly in total darkness with glowing red eyes." - // }, - // { - // "name": "Feral Weapons", - // "level": 2, - // "description": "Grow claws or fangs, gaining lethal unarmed attacks." - // }, - // { - // "name": "Metamorphosis", - // "level": 3, - // "description": "Transform your body to gain animal-like characteristics." - // } - // ] - // }, - var data interface{} - - if err := json.Unmarshal([]byte(`{ - "name": "John Doe", - "disciplines": [{ - "name": "Protean", - "level": 1, - "powers": [{ - "name": "Eyes of the Beast", - "description": "See perfectly in total darkness with glowing red eyes." - }] - }] - }`), &data); err != nil { - t.Fatalf("Failed to unmarshal test cases: %v", err) - } - - gameCharacter := domain.GameCharacter{ - Data: data, + gameCharacter := domain.GameCharacter[domain.VtmGameCharacter]{ + Data: domain.VtmGameCharacter{ + Name: "John Doe", + Disciplines: []domain.Discipline{{ + Name: "Protean", + Level: 1, + Powers: []domain.Power{{ + Name: "Eyes of the Beast", + Level: 1, + Description: "See perfectly in total darkness with glowing red eyes.", + }}, + }}, + }, } valid, err := gameCharacter.Validate()