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}