package models import ( "crypto/sha256" "encoding/json" "fmt" "sort" "strings" ) type AttributeList map[string]string type Participant struct { ID string `csv:"id" gorm:"primaryKey"` Firstname string `csv:"firstname"` Lastname string `csv:"lastname"` Token int `csv:"token"` Attributes AttributeList `csv:"attributes"` } func (p *Participant) String() string { return fmt.Sprintf("%s %s", p.Lastname, p.Firstname) } func (p *Participant) GetID() string { return p.ID } func (p *Participant) SetID(id string) { p.ID = id } func (p *Participant) GetHash() string { return fmt.Sprintf("%x", sha256.Sum256([]byte(strings.Join(append([]string{p.Lastname, p.Firstname}, p.AttributesToSlice()...), "")))) } func (p *Participant) AttributesToSlice() []string { result := make([]string, len(p.Attributes)*2) for k, v := range p.Attributes { result = append(result, k, v) } return result } func (p *Participant) Marshal() ([]byte, error) { return json.Marshal(p) } func (p *Participant) Unmarshal(data []byte) error { return json.Unmarshal(data, p) } func (al AttributeList) MarshalCSV() (string, error) { result := convertMapToKeyValueOrderedString(al) return result, nil } func (al AttributeList) UnmarshalCSV(csv string) error { al = make(map[string]string) al["foo"] = "bar" return nil } func convertMapToKeyValueOrderedString(m map[string]string) string { keys := make([]string, 0, len(m)) for key := range m { keys = append(keys, key) } sort.Strings(keys) var result strings.Builder for _, key := range keys { result.WriteString(key) result.WriteString(":") result.WriteString(m[key]) result.WriteString(",") } return strings.TrimSuffix(result.String(), ",") }