package cache import ( "context" "encoding/json" "errors" "sync" "time" ) var ErrUnsupportedDriver = errors.New("unsupported cache driver") type Store interface { Get(ctx context.Context, key string, target any) (bool, error) Set(ctx context.Context, key string, value any, ttl time.Duration) error Delete(ctx context.Context, key string) error } type memoryItem struct { value []byte expiresAt time.Time } type MemoryStore struct { mu sync.RWMutex items map[string]memoryItem } func NewMemoryStore() *MemoryStore { return &MemoryStore{ items: make(map[string]memoryItem), } } func (s *MemoryStore) Get(ctx context.Context, key string, target any) (bool, error) { if err := ctx.Err(); err != nil { return false, err } s.mu.RLock() item, ok := s.items[key] s.mu.RUnlock() if !ok { return false, nil } if !item.expiresAt.IsZero() && time.Now().After(item.expiresAt) { s.mu.Lock() delete(s.items, key) s.mu.Unlock() return false, nil } if err := json.Unmarshal(item.value, target); err != nil { return false, err } return true, nil } func (s *MemoryStore) Set(ctx context.Context, key string, value any, ttl time.Duration) error { if err := ctx.Err(); err != nil { return err } data, err := json.Marshal(value) if err != nil { return err } var expiresAt time.Time if ttl > 0 { expiresAt = time.Now().Add(ttl) } s.mu.Lock() s.items[key] = memoryItem{value: data, expiresAt: expiresAt} s.mu.Unlock() return nil } func (s *MemoryStore) Delete(ctx context.Context, key string) error { if err := ctx.Err(); err != nil { return err } s.mu.Lock() delete(s.items, key) s.mu.Unlock() return nil }