package cache import ( "encoding/json" "os" "sync" ) type Cache interface { Get(key string) (any, bool) GetDefault(key string, defaultValue any) (any, error) Set(key string, val any) error Iteration(func(key string, val any)) } type cache struct { filename string data map[string]any mu sync.Mutex } func (c *cache) Get(key string) (any, bool) { c.mu.Lock() defer c.mu.Unlock() val, ok := c.data[key] return val, ok } func (c *cache) GetDefault(key string, defaultVal any) (any, error) { c.mu.Lock() defer c.mu.Unlock() val, ok := c.data[key] if ok { return val, nil } c.data[key] = defaultVal bytes, err := json.Marshal(c.data) if err != nil { return defaultVal, err } err = os.WriteFile(c.filename, bytes, 0666) return defaultVal, err } func (c *cache) Set(key string, val any) error { c.mu.Lock() defer c.mu.Unlock() c.data[key] = val bytes, err := json.Marshal(c.data) if err != nil { return err } return os.WriteFile(c.filename, bytes, 0666) } func (c *cache) Iteration(f func(key string, val any)) { for k, v := range c.data { f(k, v) } } func NewCache(filename string) (Cache, error) { var c = &cache{ filename: filename, data: make(map[string]any), } bytes, err := os.ReadFile(filename) if err != nil { return c, nil } if err = json.Unmarshal(bytes, &c.data); err != nil { return c, err } return c, nil }