Files

99 lines
4.1 KiB
Go

// Fenrir console screen reader.
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
package config
import (
"bytes"
"fmt"
"github.com/pelletier/go-toml/v2"
)
// decode_v1 is the explicit migration boundary for the prototype's flat
// speech/sound tables. Unknown keys and mixed old/new schemas are rejected.
func decode_v1(data []byte) (Settings, error) {
defaults := Defaults()
type oldSpeech struct {
Enabled bool `toml:"enabled"`
Rate int `toml:"rate"`
Module string `toml:"module"`
Socket string `toml:"socket"`
}
old := struct {
Version int `toml:"version"`
Review Review `toml:"review"`
Speech oldSpeech `toml:"speech"`
Sound Sound `toml:"sound"`
Keyboard Keyboard `toml:"keyboard"`
Reading Reading `toml:"reading"`
Clipboard Clipboard `toml:"clipboard"`
General General `toml:"general"`
Scripts Scripts `toml:"scripts"`
Remote Remote `toml:"remote"`
}{Review: defaults.Review, Version: 1, Speech: oldSpeech{Enabled: true, Rate: defaults.Presentation.Speech.Rate}, Sound: defaults.Presentation.Sound, Keyboard: defaults.Keyboard, Reading: defaults.Reading, Clipboard: defaults.Clipboard, General: defaults.General, Scripts: defaults.Scripts, Remote: defaults.Remote}
if err := toml.NewDecoder(bytes.NewReader(data)).DisallowUnknownFields().Decode(&old); err != nil {
return Settings{}, fmt.Errorf("parse version 1 settings: %w", err)
}
defaults.Presentation.Speech.Enabled = old.Speech.Enabled
defaults.Presentation.Speech.Rate = old.Speech.Rate
defaults.Presentation.Speech.Module = old.Speech.Module
defaults.Presentation.Sound = old.Sound
defaults.Keyboard, defaults.Reading, defaults.Clipboard = old.Keyboard, old.Reading, old.Clipboard
defaults.General, defaults.Scripts, defaults.Remote = old.General, old.Scripts, old.Remote
defaults.Review = old.Review
return defaults, defaults.Validate()
}
// Version 2 briefly exposed Socket under Presentation. Migrate it away without
// carrying an endpoint override into either runtime settings or future saves.
func decode_v2(data []byte) (Settings, error) {
defaults := Defaults()
var old struct {
Version int `toml:"version"`
Review Review `toml:"review"`
Presentation struct {
Speech struct {
Speech
Socket string `toml:"socket"`
} `toml:"speech"`
Sound Sound `toml:"sound"`
} `toml:"presentation"`
Keyboard Keyboard `toml:"keyboard"`
Reading Reading `toml:"reading"`
Clipboard Clipboard `toml:"clipboard"`
General General `toml:"general"`
Scripts Scripts `toml:"scripts"`
Remote Remote `toml:"remote"`
}
old.Version = 2
old.Review = defaults.Review
old.Presentation.Speech.Speech = defaults.Presentation.Speech
old.Presentation.Sound = defaults.Presentation.Sound
old.Keyboard, old.Reading, old.Clipboard = defaults.Keyboard, defaults.Reading, defaults.Clipboard
old.General, old.Scripts, old.Remote = defaults.General, defaults.Scripts, defaults.Remote
if err := toml.NewDecoder(bytes.NewReader(data)).DisallowUnknownFields().Decode(&old); err != nil {
return Settings{}, fmt.Errorf("parse version 2 settings: %w", err)
}
defaults.Presentation.Speech = old.Presentation.Speech.Speech
defaults.Presentation.Sound = old.Presentation.Sound
defaults.Keyboard, defaults.Reading, defaults.Clipboard = old.Keyboard, old.Reading, old.Clipboard
defaults.General, defaults.Scripts, defaults.Remote = old.General, old.Scripts, old.Remote
defaults.Review = old.Review
return defaults, defaults.Validate()
}