tiny-rdm/backend/storage/preferences.go

125 lines
2.6 KiB
Go
Raw Normal View History

2023-06-27 15:53:29 +08:00
package storage
import (
"fmt"
"gopkg.in/yaml.v3"
"strings"
"sync"
)
type PreferencesStorage struct {
storage *localStorage
mutex sync.Mutex
}
func NewPreferences() *PreferencesStorage {
return &PreferencesStorage{
storage: NewLocalStore("preferences.yaml"),
}
}
func (p *PreferencesStorage) DefaultPreferences() map[string]any {
return map[string]any{
"general": map[string]any{
"language": "en",
"font": "",
"font_size": 14,
"use_proxy": false,
"use_proxy_http": false,
"check_update": true,
},
"editor": map[string]any{
"font": "",
"font_size": 14,
},
}
}
func (p *PreferencesStorage) getPreferences() (ret map[string]any) {
b, err := p.storage.Load()
if err != nil {
ret = p.DefaultPreferences()
return
}
if err := yaml.Unmarshal(b, &ret); err != nil {
ret = p.DefaultPreferences()
return
}
return
}
// GetPreferences Get preferences from local
func (p *PreferencesStorage) GetPreferences() (ret map[string]any) {
p.mutex.Lock()
defer p.mutex.Unlock()
return p.getPreferences()
}
func (p *PreferencesStorage) setPreferences(pf map[string]any, key string, value any) error {
keyPath := strings.Split(key, ".")
if len(keyPath) <= 0 {
return fmt.Errorf("invalid key path(%s)", key)
}
var node any = pf
for _, k := range keyPath[:len(keyPath)-1] {
if subNode, ok := node.(map[string]any); ok {
node = subNode[k]
} else {
return fmt.Errorf("invalid key path(%s)", key)
}
}
if subNode, ok := node.(map[string]any); ok {
subNode[keyPath[len(keyPath)-1]] = value
}
return nil
}
func (p *PreferencesStorage) savePreferences(pf map[string]any) error {
b, err := yaml.Marshal(&pf)
if err != nil {
return err
}
if err = p.storage.Store(b); err != nil {
return err
}
return nil
}
// SetPreferences assign value to key path, the key path use "." to indicate multiple level
func (p *PreferencesStorage) SetPreferences(key string, value any) error {
p.mutex.Lock()
defer p.mutex.Unlock()
pf := p.getPreferences()
if err := p.setPreferences(pf, key, value); err != nil {
return err
}
return p.savePreferences(pf)
}
// SetPreferencesN set multiple key path and value
func (p *PreferencesStorage) SetPreferencesN(values map[string]any) error {
p.mutex.Lock()
defer p.mutex.Unlock()
pf := p.getPreferences()
for path, v := range values {
if err := p.setPreferences(pf, path, v); err != nil {
return err
}
}
return p.savePreferences(pf)
}
func (p *PreferencesStorage) RestoreDefault() map[string]any {
pf := p.DefaultPreferences()
p.savePreferences(pf)
return pf
}