feat(domain): Language, a closed set carried to the engines on the context (#61)
sv and auto; an empty form value is sv, anything else is refused. LanguageFrom defaults to sv so a caller that sets nothing behaves as before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
// Language is the spoken language an upload is transcribed as. It is chosen by the user on
|
||||||
|
// the upload form and reaches the engines as one request field, so it is a closed set,
|
||||||
|
// never free text (tapir#61).
|
||||||
|
type Language string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// LangSwedish sends language=sv: the Swedish engines' own language, and what every
|
||||||
|
// upload was transcribed as before the choice existed.
|
||||||
|
LangSwedish Language = "sv"
|
||||||
|
// LangAuto sends no language, so the engine detects it. It is what "Other" on the form
|
||||||
|
// means: the Swedish-only engines are not used for it.
|
||||||
|
LangAuto Language = "auto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseLanguage reads a form value. An empty value is Swedish (a client that predates the
|
||||||
|
// field); anything that is not exactly a known value is refused rather than normalised.
|
||||||
|
func ParseLanguage(s string) (Language, bool) {
|
||||||
|
switch Language(s) {
|
||||||
|
case "", LangSwedish:
|
||||||
|
return LangSwedish, true
|
||||||
|
case LangAuto:
|
||||||
|
return LangAuto, true
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
type languageKey struct{}
|
||||||
|
|
||||||
|
// WithLanguage returns a context that carries the language of the job it serves. The
|
||||||
|
// Transcriber interface does not change: engines read it with LanguageFrom, the same way
|
||||||
|
// they read the progress Reporter (ADR-035).
|
||||||
|
func WithLanguage(ctx context.Context, l Language) context.Context {
|
||||||
|
return context.WithValue(ctx, languageKey{}, l)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LanguageFrom returns the language carried by ctx, or Swedish when it carries none, so a
|
||||||
|
// caller that sets nothing behaves as it always did.
|
||||||
|
func LanguageFrom(ctx context.Context) Language {
|
||||||
|
if l, ok := ctx.Value(languageKey{}).(Language); ok && l != "" {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
return LangSwedish
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package domain_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"git.d-ma.be/mathias/tapir/internal/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseLanguage_KnownValuesAndEmptyAreAcceptedEverythingElseIsNot(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
in string
|
||||||
|
want domain.Language
|
||||||
|
wantOK bool
|
||||||
|
}{
|
||||||
|
{"sv", domain.LangSwedish, true},
|
||||||
|
{"auto", domain.LangAuto, true},
|
||||||
|
{"", domain.LangSwedish, true}, // a client that sends no field keeps today's behaviour
|
||||||
|
{"SV", "", false}, // exact match: the value reaches a request field
|
||||||
|
{" sv", "", false},
|
||||||
|
{"sv\n", "", false},
|
||||||
|
{"en", "", false}, // a specific other language is not offered yet
|
||||||
|
{"sv,en", "", false},
|
||||||
|
{"../sv", "", false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.in, func(t *testing.T) {
|
||||||
|
got, ok := domain.ParseLanguage(tt.in)
|
||||||
|
assert.Equal(t, tt.wantOK, ok)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLanguageFrom_IsSwedishWhenTheContextCarriesNoneAndOtherwiseWhatWasSet(t *testing.T) {
|
||||||
|
assert.Equal(t, domain.LangSwedish, domain.LanguageFrom(context.Background()))
|
||||||
|
ctx := domain.WithLanguage(context.Background(), domain.LangAuto)
|
||||||
|
assert.Equal(t, domain.LangAuto, domain.LanguageFrom(ctx))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user