main
1package serde
2
3import (
4 "mime"
5 "sort"
6 "strconv"
7 "strings"
8
9 "github.com/google/jsonapi"
10)
11
12type MediaType string
13
14const (
15 JSONAPI MediaType = jsonapi.MediaType
16 JSON MediaType = "application/json"
17 Text MediaType = "text/plain"
18 YAML MediaType = "application/yaml"
19 Default MediaType = JSON
20)
21
22func (self MediaType) String() string {
23 return string(self)
24}
25
26func MediaTypeFor(value string) MediaType {
27 mediaTypes := sortedByQualityValues(strings.Split(value, ","))
28
29 for _, mediaType := range mediaTypes {
30 switch mediaType {
31 case jsonapi.MediaType:
32 return JSONAPI
33 case "application/json":
34 return JSON
35 case "text/plain":
36 return Text
37 default:
38 continue
39 }
40 }
41 return Default
42}
43
44func sortedByQualityValues(mimeTypes []string) []string {
45 weights := map[string]float64{}
46 valid := []string{}
47
48 for i, mimeType := range mimeTypes {
49 if mtype, params, err := mime.ParseMediaType(mimeType); err == nil {
50 valid = append(valid, mtype)
51 if _, ok := weights[mtype]; !ok {
52 weights[mtype] = 1.0 - (0.1 * float64(i))
53 }
54 if quality, ok := params["q"]; ok {
55 if val, err := strconv.ParseFloat(quality, 64); err == nil {
56 weights[mtype] = val
57 }
58 }
59 }
60 }
61 sort.Slice(valid, func(x, y int) bool {
62 xWeight := weights[valid[x]]
63 yWeight := weights[valid[y]]
64 return xWeight > yWeight
65 })
66 return valid
67}