Skip to content

Commit

Permalink
ctx/http
Browse files Browse the repository at this point in the history
  • Loading branch information
youthlin committed Jun 25, 2023
1 parent 4bb56f3 commit b7930c5
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 0 deletions.
44 changes: 44 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package t

import "context"

type (
typeLang struct{}
typeDomain struct{}
)

var (
keyLang = typeLang{}
keyDomain = typeDomain{}
)

func SetCtxLocale(ctx context.Context, lang string) context.Context {
return context.WithValue(ctx, keyLang, lang)
}

func SetCtxDomain(ctx context.Context, domain string) context.Context {
return context.WithValue(ctx, keyDomain, domain)
}

func GetCtxLocale(ctx context.Context) (string, bool) {
v := ctx.Value(keyLang)
lang, ok := v.(string)
return lang, ok
}

func GetCtxDomain(ctx context.Context) (string, bool) {
v := ctx.Value(keyDomain)
domain, ok := v.(string)
return domain, ok
}

func WithContext(ctx context.Context) *Translations {
t := Global()
if lang, ok := GetCtxLocale(ctx); ok {
t = t.L(lang)
}
if domain, ok := GetCtxDomain(ctx); ok {
t = t.D(domain)
}
return t
}
30 changes: 30 additions & 0 deletions context_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package t

import (
"context"
"reflect"
"testing"
)

func TestWithContext(t *testing.T) {
ctx := context.Background()
type args struct {
ctx context.Context
}
tests := []struct {
name string
args args
want *Translations
}{
{name: "init", args: args{ctx: ctx}, want: NewTranslations()},
{name: "locale", args: args{ctx: SetCtxLocale(ctx, "zh_CN")}, want: NewTranslations().L("zh_CN")},
{name: "domain", args: args{ctx: SetCtxDomain(ctx, "my-domain")}, want: NewTranslations().D("my-domain")},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := WithContext(tt.args.ctx); !reflect.DeepEqual(got, tt.want) {
t.Errorf("WithContext() = %v, want %v", got, tt.want)
}
})
}
}
39 changes: 39 additions & 0 deletions http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package t

import (
"net/http"

"golang.org/x/text/language"
)

type httpConfig struct {
cookieName string
}
type getUserLangOpt func(*httpConfig)

func WithCookieName(cookieName string) getUserLangOpt {
return func(hc *httpConfig) { hc.cookieName = cookieName }
}

const HTTPHeaderAcceptLanguage = "Accept-Language"

func GetUserLang(request *http.Request, opts ...getUserLangOpt) string {
cfg := &httpConfig{cookieName: "lang"}
for _, opt := range opts {
opt(cfg)
}
if cookie, err := request.Cookie(cfg.cookieName); err == nil {
return cookie.Value
}

langs := Locales()
var supported []language.Tag // 转换为 Tag
for _, lang := range langs {
supported = append(supported, language.Make(lang))
}
matcher := language.NewMatcher(supported) // 匹配器
acceptLangs := request.Header.Get(HTTPHeaderAcceptLanguage) // 用户支持的语言
userAccept, _, _ := language.ParseAcceptLanguage(acceptLangs) // 转为 Tag
_, index, _ := matcher.Match(userAccept...) // 找到最匹配的语言
return langs[index]
}
31 changes: 31 additions & 0 deletions http_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package t

import (
"net/http"
"testing"
)

func TestGetUserLang(t *testing.T) {
r, _ := http.NewRequest("GET", "/", nil)
r.AddCookie(&http.Cookie{Name: "language", Value: "zh_CN"})
r.Header.Add(HTTPHeaderAcceptLanguage, "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
type args struct {
request *http.Request
opts []getUserLangOpt
}
tests := []struct {
name string
args args
want string
}{
{name: "cookie", args: args{request: r, opts: []getUserLangOpt{WithCookieName("language")}}, want: "zh_CN"},
{name: "header", args: args{request: r}, want: "en_US"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetUserLang(tt.args.request, tt.args.opts...); got != tt.want {
t.Errorf("GetUserLang() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit b7930c5

Please sign in to comment.