package main import ( "encoding/json" "errors" "os" "path/filepath" ) // ErrStoryModeNoSave возвращается LoadStoryModeState, если файл // сохранения не найден (сторимод ещё не был начат). var ErrStoryModeNoSave = errors.New("файл сохранения сторимода не найден") // storyModeSavePath возвращает путь к файлу сохранения сторимода в // пользовательской конфигурационной директории. func storyModeSavePath() (string, error) { dir, err := os.UserConfigDir() if err != nil { return "", err } return filepath.Join(dir, "go-games-collection", "story_save.json"), nil } // SaveStoryModeState сохраняет текущее состояние сторимода на диск, // создавая директорию сохранения при необходимости. func SaveStoryModeState(s *StoryModeState) error { path, err := storyModeSavePath() if err != nil { return err } if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { return err } data, err := json.MarshalIndent(s, "", " ") if err != nil { return err } return os.WriteFile(path, data, 0o644) } // LoadStoryModeState загружает сохранённый сторимод с диска. // Возвращает ErrStoryModeNoSave, если файла сохранения нет — // вызывающий код должен в этом случае предложить выбрать сложность // и начать заново. func LoadStoryModeState() (*StoryModeState, error) { path, err := storyModeSavePath() if err != nil { return nil, err } data, err := os.ReadFile(path) if err != nil { if os.IsNotExist(err) { return nil, ErrStoryModeNoSave } return nil, err } var s StoryModeState if err := json.Unmarshal(data, &s); err != nil { return nil, err } return &s, nil } // DeleteStoryModeSave удаляет файл сохранения сторимода, если он // есть (используется для явного сброса прогресса). Отсутствие файла // не считается ошибкой. func DeleteStoryModeSave() error { path, err := storyModeSavePath() if err != nil { return err } err = os.Remove(path) if err != nil && !os.IsNotExist(err) { return err } return nil }