This repository has been archived by the owner on Jul 24, 2021. It is now read-only.
/
links.go
103 lines (80 loc) · 2.16 KB
/
links.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
package hypermedia
import (
"encoding/json"
"fmt"
"github.com/jtacoma/uritemplates"
)
// A hyperlink with a href/URL and a relationship
type Hyperlink struct {
Rel string
Href string
}
// Create a hyperlink to a URL
func Link(rel string, url string) Hyperlink {
return Hyperlink{rel, host + url}
}
// Create a hyperlink to a URL with a format string
func Linkf(rel string, format string, args ...interface{}) Hyperlink {
return Link(rel, fmt.Sprintf(format, args...))
}
// Create a rel:self hyperlink to a url
func Self(url string) Hyperlink {
return Link("self", url)
}
// Create a rel:self hyperlink with a format string
func Selff(format string, args ...interface{}) Hyperlink {
return Self(fmt.Sprintf(format, args...))
}
// Create a set of hyperlinks
func Links(links ...Hyperlink) HyperlinkSet {
linkmap := make(map[string]Hyperlink, len(links))
for _, link := range links {
linkmap[link.Rel] = link
}
return HyperlinkSet{linkmap}
}
// Set of hyperlinks
type HyperlinkSet struct {
links map[string]Hyperlink
}
func (l HyperlinkSet) MarshalJSON() ([]byte, error) {
out := make(map[string]map[string]string)
if l.links != nil {
for rel, link := range l.links {
out[rel] = map[string]string{
"href": link.Href,
}
}
}
return json.Marshal(out)
}
type Params map[string]interface{}
func (l *HyperlinkSet) UnmarshalJSON(d []byte) error {
var out map[string]map[string]string
if err := json.Unmarshal(d, &out); err != nil {
return err
}
l.links = make(map[string]Hyperlink, len(out))
for rel, link := range out {
l.links[rel] = Hyperlink{rel, link["href"]}
}
return nil
}
// Find the href of a link by its relationship. Returns
// "" if a link doesn't exist.
func (l HyperlinkSet) Href(rel string) (string, error) {
return l.HrefParams(rel, nil)
}
// Find the href of a link by its relationship, expanding any URI Template
// parameters with params. Returns "" if a link doesn't exist.
func (l HyperlinkSet) HrefParams(rel string, params Params) (string, error) {
link, found := l.links[rel]
if found {
template, err := uritemplates.Parse(link.Href)
if err != nil {
return "", err
}
return template.Expand(params)
}
return "", nil
}