123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * @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
- }
|