Skip to content

Instantly share code, notes, and snippets.

@SoursopID
Last active March 11, 2025 10:46
Show Gist options
  • Save SoursopID/8453bd3a923a58a2e6bd5a0966d12adb to your computer and use it in GitHub Desktop.
Save SoursopID/8453bd3a923a58a2e6bd5a0966d12adb to your computer and use it in GitHub Desktop.
Simple multi type config data with autosave
// Copyright(C) 2025 soursop
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at <https://mozilla.org/MPL/2.0/>.
// soursop is a WhatsApp bot based on whatsmeow (github.com/tulir/whatsmeow)
package config
import (
"encoding/json"
"iter"
"os"
"soursop/core/tool/pen"
"unsafe"
"github.com/alphadose/haxmap"
"golang.org/x/exp/constraints"
)
type hashable interface {
constraints.Integer | constraints.Float | constraints.Complex | ~string | uintptr | ~unsafe.Pointer
}
type ConfigType[K hashable, V any] struct {
autosave bool
filename string
data *haxmap.Map[K, V]
}
// Usage example :
//
// key = string
// value = int // it can be anything
//
// var db = NewConfigType[string, int]("config.json", true)
//
// db.Set("key", true) // for setting a key-value pair
//
// value, ok := db.Get("key") // for getting a value by key
func NewConfigType[K hashable, V any](filename string, autosave bool) *ConfigType[K, V] {
ct := &ConfigType[K, V]{
autosave: autosave,
filename: filename,
data: haxmap.New[K, V](),
}
ct.Load()
return ct
}
func (c *ConfigType[K, V]) Save() error {
f, err := os.OpenFile(c.filename, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
pen.Error(err)
return err
}
defer f.Close()
je := json.NewEncoder(f)
je.SetIndent("", " ")
return je.Encode(c.data)
}
func (c *ConfigType[K, V]) Load() error {
f, err := os.Open(c.filename)
if err != nil {
return err
}
defer f.Close()
jd := json.NewDecoder(f)
var data map[K]V
err = jd.Decode(&data)
if err != nil {
return err
}
c.data = haxmap.New[K, V]()
for k, v := range data {
c.data.Set(k, v)
}
return nil
}
func (c *ConfigType[K, V]) Set(key K, value V) {
c.data.Set(key, value)
if c.autosave {
err := c.Save()
if err != nil {
panic(err)
}
}
}
func (c *ConfigType[K, V]) Get(key K) (V, bool) {
return c.data.Get(key)
}
func (c *ConfigType[K, V]) Del(key K) {
c.data.Del(key)
if c.autosave {
c.Save()
}
}
func (c *ConfigType[K, V]) Keys() iter.Seq[K] {
return c.data.Keys()
}
func (c *ConfigType[K, V]) Clear() {
c.data.Clear()
}
func (c *ConfigType[K, V]) Len() int {
return int(c.data.Len())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment