179 lines
4 KiB
Go
179 lines
4 KiB
Go
package i18n
|
|
|
|
import (
|
|
"dappco.re/go/core"
|
|
)
|
|
|
|
func newServiceStateSnapshot(
|
|
language string,
|
|
requestedLanguage string,
|
|
languageExplicit bool,
|
|
availableLanguages []string,
|
|
mode Mode,
|
|
fallback string,
|
|
formality Formality,
|
|
location string,
|
|
direction TextDirection,
|
|
debug bool,
|
|
handlers []KeyHandler,
|
|
) ServiceState {
|
|
return ServiceState{
|
|
Language: language,
|
|
RequestedLanguage: requestedLanguage,
|
|
LanguageExplicit: languageExplicit,
|
|
AvailableLanguages: availableLanguages,
|
|
Mode: mode,
|
|
Fallback: fallback,
|
|
Formality: formality,
|
|
Location: location,
|
|
Direction: direction,
|
|
IsRTL: direction == DirRTL,
|
|
Debug: debug,
|
|
Handlers: handlers,
|
|
}
|
|
}
|
|
|
|
func defaultServiceStateSnapshot() ServiceState {
|
|
// Keep the nil/default snapshot aligned with Service.State() so callers get
|
|
// the same shape regardless of whether a Service has been initialised.
|
|
return newServiceStateSnapshot(
|
|
"en",
|
|
"",
|
|
false,
|
|
[]string{},
|
|
ModeNormal,
|
|
"en",
|
|
FormalityNeutral,
|
|
"",
|
|
DirLTR,
|
|
false,
|
|
[]KeyHandler{},
|
|
)
|
|
}
|
|
|
|
// ServiceState captures the current configuration of a service in one
|
|
// copy-safe snapshot.
|
|
//
|
|
// state := i18n.CurrentState()
|
|
type ServiceState struct {
|
|
Language string
|
|
RequestedLanguage string
|
|
LanguageExplicit bool
|
|
AvailableLanguages []string
|
|
Mode Mode
|
|
Fallback string
|
|
Formality Formality
|
|
Location string
|
|
Direction TextDirection
|
|
IsRTL bool
|
|
Debug bool
|
|
Handlers []KeyHandler
|
|
}
|
|
|
|
// HandlerTypeNames returns the short type names of the snapshot's handlers.
|
|
//
|
|
// names := i18n.CurrentState().HandlerTypeNames()
|
|
//
|
|
// The returned slice is a fresh copy, so callers can inspect or mutate it
|
|
// without affecting the snapshot.
|
|
func (s ServiceState) HandlerTypeNames() []string {
|
|
if len(s.Handlers) == 0 {
|
|
return []string{}
|
|
}
|
|
names := make([]string, 0, len(s.Handlers))
|
|
for _, handler := range s.Handlers {
|
|
if handler == nil {
|
|
names = append(names, "<nil>")
|
|
continue
|
|
}
|
|
names = append(names, shortHandlerTypeName(handler))
|
|
}
|
|
return names
|
|
}
|
|
|
|
// String returns a concise, stable summary of the service snapshot.
|
|
//
|
|
// fmt.Println(i18n.CurrentState().String())
|
|
func (s ServiceState) String() string {
|
|
langs := "[]"
|
|
if len(s.AvailableLanguages) > 0 {
|
|
langs = "[" + core.Join(", ", s.AvailableLanguages...) + "]"
|
|
}
|
|
handlerNames := s.HandlerTypeNames()
|
|
handlers := "[]"
|
|
if len(handlerNames) > 0 {
|
|
handlers = "[" + core.Join(", ", handlerNames...) + "]"
|
|
}
|
|
return core.Sprintf(
|
|
"ServiceState{language=%q requested=%q explicit=%t fallback=%q mode=%s formality=%s location=%q direction=%s rtl=%t debug=%t available=%s handlers=%d types=%s}",
|
|
s.Language,
|
|
s.RequestedLanguage,
|
|
s.LanguageExplicit,
|
|
s.Fallback,
|
|
s.Mode,
|
|
s.Formality,
|
|
s.Location,
|
|
s.Direction,
|
|
s.IsRTL,
|
|
s.Debug,
|
|
langs,
|
|
len(s.Handlers),
|
|
handlers,
|
|
)
|
|
}
|
|
|
|
func shortHandlerTypeName(handler KeyHandler) string {
|
|
name := core.Sprintf("%T", handler)
|
|
parts := core.Split(name, ".")
|
|
if len(parts) > 0 {
|
|
name = parts[len(parts)-1]
|
|
}
|
|
return core.TrimPrefix(name, "*")
|
|
}
|
|
|
|
func (s *Service) State() ServiceState {
|
|
if s == nil {
|
|
return defaultServiceStateSnapshot()
|
|
}
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
|
|
langs := make([]string, len(s.availableLangs))
|
|
for i, tag := range s.availableLangs {
|
|
langs[i] = tag.String()
|
|
}
|
|
|
|
handlers := make([]KeyHandler, len(s.handlers))
|
|
copy(handlers, s.handlers)
|
|
|
|
dir := DirLTR
|
|
if IsRTLLanguage(s.currentLang) {
|
|
dir = DirRTL
|
|
}
|
|
|
|
return newServiceStateSnapshot(
|
|
s.currentLang,
|
|
s.requestedLang,
|
|
s.languageExplicit,
|
|
langs,
|
|
s.mode,
|
|
s.fallbackLang,
|
|
s.formality,
|
|
s.location,
|
|
dir,
|
|
s.debug,
|
|
handlers,
|
|
)
|
|
}
|
|
|
|
// String returns a concise snapshot of the service state.
|
|
func (s *Service) String() string {
|
|
return s.State().String()
|
|
}
|
|
|
|
// CurrentState is a more explicit alias for State.
|
|
//
|
|
// state := i18n.CurrentState()
|
|
func (s *Service) CurrentState() ServiceState {
|
|
return s.State()
|
|
}
|