package services import ( "fmt" "log" "sort" "time" tspb "google.golang.org/protobuf/types/known/timestamppb" ) type EntityStore[T any] struct { IDCount int Entities map[string]*T // Getters/Setters for ID IDSetter func(entity *T, id string) IDGetter func(entity *T) string // Getters/Setters for created timestamp CreatedAtSetter func(entity *T, ts *tspb.Timestamp) CreatedAtGetter func(entity *T) *tspb.Timestamp // Getters/Setters for udpated timestamp UpdatedAtSetter func(entity *T, ts *tspb.Timestamp) UpdatedAtGetter func(entity *T) *tspb.Timestamp } func NewEntityStore[T any]() *EntityStore[T] { return &EntityStore[T]{ Entities: make(map[string]*T), } } func (s *EntityStore[T]) Create(entity *T) *T { s.IDCount++ newid := fmt.Sprintf("%d", s.IDCount) s.Entities[newid] = entity s.IDSetter(entity, newid) s.CreatedAtSetter(entity, tspb.New(time.Now())) s.UpdatedAtSetter(entity, tspb.New(time.Now())) return entity } func (s *EntityStore[T]) Get(id string) *T { if entity, ok := s.Entities[id]; ok { return entity } return nil } func (s *EntityStore[T]) BatchGet(ids []string) map[string]*T { out := make(map[string]*T) for _, id := range ids { if entity, ok := s.Entities[id]; ok { out[id] = entity } } return out } // Updates specific fields of an Entity func (s *EntityStore[T]) Update(entity *T) *T { s.UpdatedAtSetter(entity, tspb.New(time.Now())) return entity } // Deletes an entity from our system. func (s *EntityStore[T]) Delete(id string) bool { _, ok := s.Entities[id] if ok { delete(s.Entities, id) } return ok } // Finds and retrieves entity matching the particular criteria. func (s *EntityStore[T]) List(ltfunc func(t1, t2 *T) bool, filterfunc func(t *T) bool) (out []*T) { log.Println("E: ", s.Entities) for _, ent := range s.Entities { if filterfunc == nil || filterfunc(ent) { out = append(out, ent) } } // Sort in reverse order of name sort.Slice(out, func(idx1, idx2 int) bool { ent1 := out[idx1] ent2 := out[idx2] return ltfunc(ent1, ent2) }) return }