Files
seriatim/internal/speaker/map.go

70 lines
1.8 KiB
Go

package speaker
import (
"fmt"
"os"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
// Map resolves input file basenames to canonical speaker names.
type Map struct {
inputs map[string]Input
}
// Input describes one input entry in speakers.yml.
type Input struct {
Speaker string `yaml:"speaker"`
}
type fileSchema struct {
Inputs map[string]Input `yaml:"inputs"`
}
// LoadMap parses a speakers.yml file.
func LoadMap(path string) (Map, error) {
data, err := os.ReadFile(path)
if err != nil {
return Map{}, err
}
var parsed fileSchema
if err := yaml.Unmarshal(data, &parsed); err != nil {
return Map{}, fmt.Errorf("parse speaker map %q: %w", path, err)
}
if len(parsed.Inputs) == 0 {
return Map{}, fmt.Errorf("speaker map %q must contain at least one inputs entry", path)
}
inputs := make(map[string]Input, len(parsed.Inputs))
for key, input := range parsed.Inputs {
basename := filepath.Base(strings.TrimSpace(key))
if basename == "." || basename == "" {
return Map{}, fmt.Errorf("speaker map %q contains an empty input key", path)
}
if _, exists := inputs[basename]; exists {
return Map{}, fmt.Errorf("speaker map %q contains duplicate basename mapping for %q", path, basename)
}
input.Speaker = strings.TrimSpace(input.Speaker)
if input.Speaker == "" {
return Map{}, fmt.Errorf("speaker map entry %q must include speaker", basename)
}
inputs[basename] = input
}
return Map{inputs: inputs}, nil
}
// SpeakerForSource returns the canonical speaker for a transcript source path.
func (m Map) SpeakerForSource(source string) (string, error) {
basename := filepath.Base(source)
input, ok := m.inputs[basename]
if !ok {
return "", fmt.Errorf("speaker map has no entry for input basename %q", basename)
}
return input.Speaker, nil
}