package i18n import ( "context" _ "embed" "encoding/json" "fmt" "strings" "sync" "git.dmitriygnatenko.ru/dima/go-common/logger" "github.com/gofiber/fiber/v2" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/models" ) //go:embed ru.json var ruJsonContent []byte //go:embed en.json var enJsonContent []byte const ( langParam = "lang" ru = "ru" en = "en" ) type Language string var ( once sync.Once i18n *I18n ) type I18n struct { translations map[Language]map[string]string languages map[Language]models.Language defaultLanguage Language } func Init(req []models.Language) error { var err error once.Do(func() { var defaultLanguage Language translations := make(map[Language]map[string]string) languages := make(map[Language]models.Language) for i := range req { if req[i].IsDefault { defaultLanguage = Language(strings.ToLower(req[i].URL)) } url := strings.ToLower(req[i].URL) languages[Language(url)] = req[i] switch url { case ru: ruTranslations := make(map[string]string) err = json.Unmarshal(ruJsonContent, &ruTranslations) if err != nil { logger.Warn(context.Background(), err.Error()) continue } translations[Language(url)] = ruTranslations case en: enTranslations := make(map[string]string) err = json.Unmarshal(enJsonContent, &enTranslations) if err != nil { logger.Warn(context.Background(), err.Error()) continue } translations[Language(url)] = enTranslations } } i18n = &I18n{ translations: translations, defaultLanguage: defaultLanguage, languages: languages, } }) return err } func T(lang Language, key string, args ...any) string { if i18n == nil { logger.Error(context.Background(), "i18n not initialized") return "" } if i18n.translations[lang] == nil { logger.Warnf(context.Background(), "i18n: language %s not initialized", lang) return "" } var translated string if len(args) == 0 { translated = i18n.translations[lang][key] } else { translated = fmt.Sprintf(i18n.translations[lang][key], args...) } if len(translated) == 0 { logger.Warnf( context.Background(), "i18n: language %s translation %s is not found", lang, key, ) } return translated } func DefaultLanguage() Language { if i18n == nil { logger.Error(context.Background(), "i18n not initialized") return "" } return i18n.defaultLanguage } func LanguageFromContext(c *fiber.Ctx) Language { language := c.Params(langParam) if len(language) > 0 { return Language(language) } return DefaultLanguage() } func LanguageID(lang Language) models.LanguageID { if i18n == nil { logger.Error(context.Background(), "i18n not initialized") return 0 } if language, ok := i18n.languages[lang]; ok { return language.ID } logger.Errorf( context.Background(), "i18n: language ID for %s language is not found", lang, ) return 0 } func LanguageFromID(id models.LanguageID) Language { if i18n == nil { logger.Error(context.Background(), "i18n not initialized") return DefaultLanguage() } for lang, modelLang := range i18n.languages { if modelLang.ID == id { return lang } } return DefaultLanguage() }