+13
atproto/syntax/atidentifier.go
+13
atproto/syntax/atidentifier.go
···
59
59
}
60
60
return ""
61
61
}
62
+
63
+
func (a AtIdentifier) MarshalText() ([]byte, error) {
64
+
return []byte(a.String()), nil
65
+
}
66
+
67
+
func (a *AtIdentifier) UnmarshalText(text []byte) error {
68
+
atid, err := ParseAtIdentifier(string(text))
69
+
if err != nil {
70
+
return err
71
+
}
72
+
*a = *atid
73
+
return nil
74
+
}
+13
atproto/syntax/aturi.go
+13
atproto/syntax/aturi.go
···
101
101
}
102
102
return ATURI("at://" + auth.Normalize().String() + "/" + coll.Normalize().String() + "/" + rkey.String())
103
103
}
104
+
105
+
func (a ATURI) MarshalText() ([]byte, error) {
106
+
return []byte(a.String()), nil
107
+
}
108
+
109
+
func (a *ATURI) UnmarshalText(text []byte) error {
110
+
aturi, err := ParseATURI(string(text))
111
+
if err != nil {
112
+
return err
113
+
}
114
+
*a = aturi
115
+
return nil
116
+
}
+13
atproto/syntax/did.go
+13
atproto/syntax/did.go
···
49
49
func (d DID) String() string {
50
50
return string(d)
51
51
}
52
+
53
+
func (d DID) MarshalText() ([]byte, error) {
54
+
return []byte(d.String()), nil
55
+
}
56
+
57
+
func (d *DID) UnmarshalText(text []byte) error {
58
+
did, err := ParseDID(string(text))
59
+
if err != nil {
60
+
return err
61
+
}
62
+
*d = did
63
+
return nil
64
+
}
+14
-1
atproto/syntax/handle.go
+14
-1
atproto/syntax/handle.go
···
20
20
return "", fmt.Errorf("handle is too long (253 chars max)")
21
21
}
22
22
if !handleRegex.MatchString(raw) {
23
-
return "", fmt.Errorf("handle syntax didn't validate via regex")
23
+
return "", fmt.Errorf("handle syntax didn't validate via regex: %s", raw)
24
24
}
25
25
return Handle(raw), nil
26
26
}
···
56
56
func (h Handle) String() string {
57
57
return string(h)
58
58
}
59
+
60
+
func (h Handle) MarshalText() ([]byte, error) {
61
+
return []byte(h.String()), nil
62
+
}
63
+
64
+
func (h *Handle) UnmarshalText(text []byte) error {
65
+
handle, err := ParseHandle(string(text))
66
+
if err != nil {
67
+
return err
68
+
}
69
+
*h = handle
70
+
return nil
71
+
}
+6
atproto/syntax/handle_test.go
+6
atproto/syntax/handle_test.go
+84
atproto/syntax/json_test.go
+84
atproto/syntax/json_test.go
···
1
+
package syntax
2
+
3
+
import (
4
+
"encoding/json"
5
+
"testing"
6
+
7
+
"github.com/stretchr/testify/assert"
8
+
)
9
+
10
+
func TestJSONEncoding(t *testing.T) {
11
+
assert := assert.New(t)
12
+
13
+
type AllTogether struct {
14
+
Handle Handle `json:"handle"`
15
+
Aturi ATURI `json:"aturi"`
16
+
Did DID `json:"did"`
17
+
Atid *AtIdentifier `json:"atid"`
18
+
Rkey RecordKey `json:"rkey"`
19
+
Col *NSID `json:"col"` // demonstrating a pointer
20
+
}
21
+
fullJSON := `{
22
+
"handle": "handle.example.com",
23
+
"aturi": "at://handle.example.com/not.atproto.thing/abc123",
24
+
"did": "did:abc:123",
25
+
"atid": "did:abc:123",
26
+
"rkey": "abc123",
27
+
"col": "not.atproto.thing"
28
+
}`
29
+
assert.Equal(json.Valid([]byte(fullJSON)), true)
30
+
31
+
handle, err := ParseHandle("handle.example.com")
32
+
assert.NoError(err)
33
+
aturi, err := ParseATURI("at://handle.example.com/not.atproto.thing/abc123")
34
+
assert.NoError(err)
35
+
did, err := ParseDID("did:abc:123")
36
+
assert.NoError(err)
37
+
atid, err := ParseAtIdentifier("did:abc:123")
38
+
assert.NoError(err)
39
+
rkey, err := ParseRecordKey("abc123")
40
+
assert.NoError(err)
41
+
col, err := ParseNSID("not.atproto.thing")
42
+
assert.NoError(err)
43
+
44
+
fullStruct := AllTogether{
45
+
Handle: handle,
46
+
Aturi: aturi,
47
+
Did: did,
48
+
Atid: atid,
49
+
Rkey: rkey,
50
+
Col: &col,
51
+
}
52
+
53
+
_, err = json.Marshal(fullStruct)
54
+
assert.NoError(err)
55
+
56
+
var parseStruct AllTogether
57
+
err = json.Unmarshal([]byte(fullJSON), &parseStruct)
58
+
assert.NoError(err)
59
+
assert.Equal(fullStruct, parseStruct)
60
+
61
+
badJSON := `{"handle": 12343}`
62
+
err = json.Unmarshal([]byte(badJSON), &parseStruct)
63
+
assert.Error(err)
64
+
65
+
wrongJSON := `{"handle": "asdf"}`
66
+
err = json.Unmarshal([]byte(wrongJSON), &parseStruct)
67
+
assert.Error(err)
68
+
69
+
okJSON := `{"handle": "blah.com"}`
70
+
err = json.Unmarshal([]byte(okJSON), &parseStruct)
71
+
assert.NoError(err)
72
+
}
73
+
74
+
func TestJSONHandle(t *testing.T) {
75
+
assert := assert.New(t)
76
+
77
+
blob := `["atproto.com", "bsky.app"]`
78
+
var handleList []Handle
79
+
if err := json.Unmarshal([]byte(blob), &handleList); err != nil {
80
+
t.Fatal(err)
81
+
}
82
+
assert.Equal(Handle("atproto.com"), handleList[0])
83
+
assert.Equal(Handle("bsky.app"), handleList[1])
84
+
}
+13
atproto/syntax/nsid.go
+13
atproto/syntax/nsid.go
···
60
60
prefix := strings.ToLower(strings.Join(parts[:len(parts)-1], "."))
61
61
return NSID(prefix + "." + name)
62
62
}
63
+
64
+
func (n NSID) MarshalText() ([]byte, error) {
65
+
return []byte(n.String()), nil
66
+
}
67
+
68
+
func (n *NSID) UnmarshalText(text []byte) error {
69
+
nsid, err := ParseNSID(string(text))
70
+
if err != nil {
71
+
return err
72
+
}
73
+
*n = nsid
74
+
return nil
75
+
}
+13
atproto/syntax/recordkey.go
+13
atproto/syntax/recordkey.go
···
30
30
func (r RecordKey) String() string {
31
31
return string(r)
32
32
}
33
+
34
+
func (r RecordKey) MarshalText() ([]byte, error) {
35
+
return []byte(r.String()), nil
36
+
}
37
+
38
+
func (r *RecordKey) UnmarshalText(text []byte) error {
39
+
rkey, err := ParseRecordKey(string(text))
40
+
if err != nil {
41
+
return err
42
+
}
43
+
*r = rkey
44
+
return nil
45
+
}