config.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package config
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log/slog"
  6. "os"
  7. "github.com/BurntSushi/toml"
  8. "github.com/sst/opencode/pkg/client"
  9. )
  10. type State struct {
  11. Theme string `toml:"theme"`
  12. Provider string `toml:"provider"`
  13. Model string `toml:"model"`
  14. }
  15. func NewState() *State {
  16. return &State{
  17. Theme: "opencode",
  18. }
  19. }
  20. func MergeState(state *State, config *client.ConfigInfo) *client.ConfigInfo {
  21. if config.Theme == nil {
  22. config.Theme = &state.Theme
  23. }
  24. return config
  25. }
  26. // SaveState writes the provided Config struct to the specified TOML file.
  27. // It will create the file if it doesn't exist, or overwrite it if it does.
  28. func SaveState(filePath string, state *State) error {
  29. file, err := os.Create(filePath)
  30. if err != nil {
  31. return fmt.Errorf("failed to create/open config file %s: %w", filePath, err)
  32. }
  33. defer file.Close()
  34. writer := bufio.NewWriter(file)
  35. encoder := toml.NewEncoder(writer)
  36. if err := encoder.Encode(state); err != nil {
  37. return fmt.Errorf("failed to encode state to TOML file %s: %w", filePath, err)
  38. }
  39. if err := writer.Flush(); err != nil {
  40. return fmt.Errorf("failed to flush writer for state file %s: %w", filePath, err)
  41. }
  42. slog.Debug("State saved to file", "file", filePath)
  43. return nil
  44. }
  45. // LoadState loads the state from the specified TOML file.
  46. // It returns a pointer to the State struct and an error if any issues occur.
  47. func LoadState(filePath string) (*State, error) {
  48. var state State
  49. if _, err := toml.DecodeFile(filePath, &state); err != nil {
  50. if _, statErr := os.Stat(filePath); os.IsNotExist(statErr) {
  51. return nil, fmt.Errorf("state file not found at %s: %w", filePath, statErr)
  52. }
  53. return nil, fmt.Errorf("failed to decode TOML from file %s: %w", filePath, err)
  54. }
  55. return &state, nil
  56. }