Skip to content

Commit

Permalink
Fix: concurrency safe (#32)
Browse files Browse the repository at this point in the history
fix #21 
fix #27 

Co-authored-by: Bo-Yi Wu <[email protected]>
  • Loading branch information
jonesyang12 and appleboy authored Jul 27, 2023
1 parent 4be4d75 commit b8f7fd2
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 49 deletions.
4 changes: 2 additions & 2 deletions embed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ func newEmbedServer(middleware ...gin.HandlerFunc) *server {
server.Use(middleware...)

server.GET("/", func(context *gin.Context) {
context.String(http.StatusOK, MustGetMessage("welcome"))
context.String(http.StatusOK, MustGetMessage(context, "welcome"))
})

server.GET("/:name", func(context *gin.Context) {
context.String(http.StatusOK, MustGetMessage(&i18n.LocalizeConfig{
context.String(http.StatusOK, MustGetMessage(context, &i18n.LocalizeConfig{
MessageID: "welcomeWithName",
TemplateData: map[string]string{
"name": context.Param("name"),
Expand Down
14 changes: 4 additions & 10 deletions ginI18n.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package i18n

import (
"context"
"errors"
"fmt"
"path"
Expand All @@ -15,15 +14,14 @@ var _ GinI18n = (*ginI18nImpl)(nil)

type ginI18nImpl struct {
bundle *i18n.Bundle
currentContext *gin.Context
localizerByLng map[string]*i18n.Localizer
defaultLanguage language.Tag
getLngHandler GetLngHandler
}

// getMessage get localize message by lng and messageID
func (i *ginI18nImpl) getMessage(param interface{}) (string, error) {
lng := i.getLngHandler(i.currentContext, i.defaultLanguage.String())
func (i *ginI18nImpl) getMessage(ctx *gin.Context, param interface{}) (string, error) {
lng := i.getLngHandler(ctx, i.defaultLanguage.String())
localizer := i.getLocalizerByLng(lng)

localizeConfig, err := i.getLocalizeConfig(param)
Expand All @@ -40,15 +38,11 @@ func (i *ginI18nImpl) getMessage(param interface{}) (string, error) {
}

// mustGetMessage ...
func (i *ginI18nImpl) mustGetMessage(param interface{}) string {
message, _ := i.getMessage(param)
func (i *ginI18nImpl) mustGetMessage(ctx *gin.Context, param interface{}) string {
message, _ := i.getMessage(ctx, param)
return message
}

func (i *ginI18nImpl) setCurrentContext(ctx context.Context) {
i.currentContext = ctx.(*gin.Context)
}

func (i *ginI18nImpl) setBundle(cfg *BundleCfg) {
bundle := i18n.NewBundle(cfg.DefaultLanguage)
bundle.RegisterUnmarshalFunc(cfg.FormatBundleFile, cfg.UnmarshalFunc)
Expand Down
65 changes: 34 additions & 31 deletions i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import (
"github.com/gin-gonic/gin"
)

var atI18n GinI18n

// newI18n ...
func newI18n(opts ...Option) {
func newI18n(opts ...Option) GinI18n {
// init ins
ins := &ginI18nImpl{}

Expand All @@ -26,44 +24,49 @@ func newI18n(opts ...Option) {
ins.getLngHandler = defaultGetLngHandler
}

atI18n = ins
return ins
}

// Localize ...
func Localize(opts ...Option) gin.HandlerFunc {
newI18n(opts...)
atI18n := newI18n(opts...)
return func(context *gin.Context) {
atI18n.setCurrentContext(context)
context.Set("i18n", atI18n)
}
}

// GetMessage get the i18n message
/*
GetMessage get the i18n message
// param is one of these type: messageID, *i18n.LocalizeConfig
// Example:
// GetMessage("hello") // messageID is hello
//
// GetMessage(&i18n.LocalizeConfig{
// MessageID: "welcomeWithName",
// TemplateData: map[string]string{
// "name": context.Param("name"),
// },
// })
func GetMessage(param interface{}) (string, error) {
return atI18n.getMessage(param)
param is one of these type: messageID, *i18n.LocalizeConfig
Example:
GetMessage(context, "hello") // messageID is hello
GetMessage(context, &i18n.LocalizeConfig{
MessageID: "welcomeWithName",
TemplateData: map[string]string{
"name": context.Param("name"),
},
})
*/
func GetMessage(context *gin.Context, param interface{}) (string, error) {
atI18n := context.Value("i18n").(GinI18n)
return atI18n.getMessage(context, param)
}

// MustGetMessage get the i18n message without error handling
// param is one of these type: messageID, *i18n.LocalizeConfig
// Example:
// MustGetMessage("hello") // messageID is hello
/*
MustGetMessage get the i18n message without error handling
// MustGetMessage(&i18n.LocalizeConfig{
// MessageID: "welcomeWithName",
// TemplateData: map[string]string{
// "name": context.Param("name"),
// },
// })
func MustGetMessage(param interface{}) string {
return atI18n.mustGetMessage(param)
param is one of these type: messageID, *i18n.LocalizeConfig
Example:
MustGetMessage(context, "hello") // messageID is hello
MustGetMessage(context, &i18n.LocalizeConfig{
MessageID: "welcomeWithName",
TemplateData: map[string]string{
"name": context.Param("name"),
},
})
*/
func MustGetMessage(context *gin.Context, param interface{}) string {
atI18n := context.MustGet("i18n").(GinI18n)
return atI18n.mustGetMessage(context, param)
}
4 changes: 2 additions & 2 deletions i18n_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ func newServer() *gin.Engine {
router.Use(Localize())

router.GET("/", func(context *gin.Context) {
context.String(http.StatusOK, MustGetMessage("welcome"))
context.String(http.StatusOK, MustGetMessage(context, "welcome"))
})

router.GET("/:name", func(context *gin.Context) {
context.String(http.StatusOK, MustGetMessage(&i18n.LocalizeConfig{
context.String(http.StatusOK, MustGetMessage(context, &i18n.LocalizeConfig{
MessageID: "welcomeWithName",
TemplateData: map[string]string{
"name": context.Param("name"),
Expand Down
7 changes: 3 additions & 4 deletions interface.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package i18n

import (
"context"
"github.com/gin-gonic/gin"
)

// GinI18n ...
type GinI18n interface {
getMessage(param interface{}) (string, error)
mustGetMessage(param interface{}) string
setCurrentContext(ctx context.Context)
getMessage(context *gin.Context, param interface{}) (string, error)
mustGetMessage(context *gin.Context, param interface{}) string
setBundle(cfg *BundleCfg)
setGetLngHandler(handler GetLngHandler)
}

0 comments on commit b8f7fd2

Please sign in to comment.