package state import ( "encoding/gob" "os" "ripple/types" ) const errSaveFailed = "save failed" type State struct { Storage Storage Memory Memory } func newState() *State { return &State{ Memory: Memory{ Commit: make(map[types.UserIdentifier]map[[32]byte]struct{}), Pathfinding: make(map[[32]byte]Pathfinding), }, } } func (s *State) MustSave() { if err := s.Save(); err != nil { panic(errSaveFailed) } } func (s *State) Save() error { filePath, err := storagePath() if err != nil { return err } f, err := os.Create(filePath) if err != nil { return err } defer f.Close() enc := gob.NewEncoder(f) return enc.Encode(s.Storage) } func Load() (*State, error) { filePath, err := storagePath() if err != nil { return nil, err } f, err := os.Open(filePath) if err != nil { return nil, err } defer f.Close() dec := gob.NewDecoder(f) st := newState() if err := dec.Decode(&st.Storage); err != nil { return nil, err } return st, nil } func (s *State) AddAccount(id types.UserIdentifier, port int, secretKey [32]byte) error { if err := s.Storage.AddAccount(id, port, secretKey); err != nil { return err } s.Memory.AddAccount(id) return s.Save() } func (s *State) RemoveAccount(id types.UserIdentifier) error { s.Memory.RemoveAccount(id) s.Storage.RemoveAccount(id) return s.Save() }