forked from go-admin-team/go-admin-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.go
111 lines (87 loc) · 2.39 KB
/
parser.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* @Author: lwnmengjing
* @Date: 2021/6/9 10:59 上午
* @Last Modified by: lwnmengjing
* @Last Modified time: 2021/6/9 10:59 上午
*/
package language
import (
"sort"
"strconv"
"strings"
)
type language struct {
name string
quality float64
}
type languageSlice []language
func (e languageSlice) SortByQuality() {
sort.Sort(e)
}
func (e languageSlice) Len() int {
return len(e)
}
func (e languageSlice) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}
func (e languageSlice) Less(i, j int) bool {
return e[i].quality > e[j].quality
}
// ParseAcceptLanguage returns RFC1766 language codes parsed and sorted from
// languages.
//
// If supportedLanguages is not empty, the returned codes will be filtered
// by its contents.
func ParseAcceptLanguage(languages string, supportedLanguages []string) []string {
preferredLanguages := strings.Split(languages, ",")
preferredLanguagesLen := len(preferredLanguages)
// Preallocate processed languages, as we know the maximum possible.
langCap := preferredLanguagesLen
if len(supportedLanguages) > 0 {
langCap = len(supportedLanguages)
}
langs := make(languageSlice, 0, langCap)
for i, rawPreferredLanguage := range preferredLanguages {
// Format strings.
preferredLanguage := strings.Replace(strings.ToLower(strings.TrimSpace(rawPreferredLanguage)), "_", "-", 0)
if preferredLanguage == "" {
continue
}
// Split out quality factor.
parts := strings.SplitN(preferredLanguage, ";", 2)
// If supported languages are given, return only the langs that fit.
supported := len(supportedLanguages) == 0
for _, supportedLanguage := range supportedLanguages {
if supported = supportedLanguage == parts[0]; supported {
break
}
}
if !supported {
continue
}
lang := language{parts[0], 0}
if len(parts) == 2 {
q := parts[1]
if strings.HasPrefix(q, "q=") {
q = strings.SplitN(q, "=", 2)[1]
var err error
if lang.quality, err = strconv.ParseFloat(q, 64); err != nil {
// Default value (1) if quality is empty.
lang.quality = 1
}
}
}
// Use order of items if no quality is given.
if lang.quality == 0 {
lang.quality = float64(preferredLanguagesLen - i)
}
langs = append(langs, lang)
}
langs.SortByQuality()
// Filter quality string.
langString := make([]string, 0, len(langs))
for _, lang := range langs {
langString = append(langString, lang.name)
}
return langString
}