forked from jirenius/go-res
-
Notifications
You must be signed in to change notification settings - Fork 1
/
types.go
74 lines (63 loc) · 1.44 KB
/
types.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
package res
import "encoding/json"
// Ref is a resource reference to another resource ID.
// It marshals into a reference object, eg.:
// {"rid":"userService.user.42"}
type Ref string
// ResourceType enum
type ResourceType byte
// Resource type enum values
const (
TypeUnset ResourceType = iota
TypeModel
TypeCollection
)
var refPrefix = []byte(`{"rid":`)
const refSuffix = '}'
// DeleteAction is used for deleted properties in "change" events
var DeleteAction = &struct{ json.RawMessage }{RawMessage: json.RawMessage(`{"action":"delete"}`)}
// MarshalJSON makes Ref implement the json.Marshaler interface.
func (r Ref) MarshalJSON() ([]byte, error) {
rid, err := json.Marshal(string(r))
if err != nil {
return nil, err
}
o := make([]byte, len(rid)+8)
copy(o, refPrefix)
copy(o[7:], rid)
o[len(o)-1] = refSuffix
return o, nil
}
// UnmarshalJSON makes Ref implement the json.Unmarshaler interface.
func (r *Ref) UnmarshalJSON(b []byte) error {
var p struct {
RID string `json:"rid"`
}
err := json.Unmarshal(b, &p)
if err != nil {
return err
}
*r = Ref(p.RID)
return nil
}
// IsValid returns true if the reference RID is valid, otherwise false.
func (r Ref) IsValid() bool {
start := true
for _, c := range r {
if c == '?' {
return !start
}
if c < 33 || c > 126 || c == '*' || c == '>' {
return false
}
if c == '.' {
if start {
return false
}
start = true
} else {
start = false
}
}
return !start
}