package entity import ( "fmt" "os" r "xyj-figures/pkg/relationship" yaml "gopkg.in/yaml.v3" ) type Entity struct { Schema string `yaml:"schema,flow"` Type string `yaml:"type,flow"` Details interface{} `yaml:"details,flow"` } type EntityType string const ( EntityTypeCharacter = "character" EntityTypeGroup = "group" ) type EntityDetails interface { GetRelationships() []r.Relationship } func NewEntity() (*Entity, error) { return &Entity{Schema: "v1"}, nil } func Load(path string) (*Entity, error) { f, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("failed to open file: %v", err) } e, _ := NewEntity() if err = yaml.Unmarshal(f, &e); err != nil { return nil, fmt.Errorf("failed to unmarshal file: %v", err) } switch e.Type { case EntityTypeCharacter: tmp, err := yaml.Marshal(e.Details) if err != nil { return nil, fmt.Errorf("failed to marshal filed %s: %v", EntityTypeCharacter, err) } c := Character{} if err = yaml.Unmarshal(tmp, &c); err != nil { return nil, fmt.Errorf("failed to unmarshal filed %s: %v", EntityTypeCharacter, err) } e.Details = c case EntityTypeGroup: tmp, err := yaml.Marshal(e.Details) if err != nil { return nil, fmt.Errorf("failed to marshal filed %s: %v", EntityTypeGroup, err) } g := Group{} if err = yaml.Unmarshal(tmp, &g); err != nil { return nil, fmt.Errorf("failed to unmarshal filed %s: %v", EntityTypeGroup, err) } e.Details = g } return e, nil } func (e Entity) Merge(other Entity) error { if (e.Schema != other.Schema) || (e.Type != other.Type) { return fmt.Errorf("unmatch merge between %v and %v", e, other) } switch e.Type { case EntityTypeCharacter: if e.Details.(Character).Name != other.Details.(Character).Name { return fmt.Errorf("unmatch merge between %v and %v: names unmatch", e, other) } e.Details = Character{ Name: e.Details.(Character).Name, OtherNames: append(e.Details.(Character).OtherNames, other.Details.(Character).OtherNames...), Relationships: append(e.Details.(Character).Relationships, other.Details.(Character).Relationships...), Description: fmt.Sprintf("%s%s", e.Details.(Character).Description, other.Details.(Character).Description), Links: append(e.Details.(Character).Links, other.Details.(Character).Links...), } case EntityTypeGroup: e.Details = Group{ Name: e.Details.(Group).Name, OtherNames: append(e.Details.(Group).OtherNames, other.Details.(Group).OtherNames...), Members: append(e.Details.(Group).Members, other.Details.(Group).Members...), Relationships: append(e.Details.(Group).Relationships, other.Details.(Group).Relationships...), Description: fmt.Sprintf("%s%s", e.Details.(Group).Description, other.Details.(Group).Description), Links: append(e.Details.(Group).Links, other.Details.(Group).Links...), } } return nil }