Skip to content

Commit a61de15

Browse files
authored
implement TextMarshaler/JSONMarshaler more consistently (#2097)
* implement TextMarshaler/JSONMarshaler more consistently Signed-off-by: Jason Hall <[email protected]> * ensure satisfaction Signed-off-by: Jason Hall <[email protected]> --------- Signed-off-by: Jason Hall <[email protected]>
1 parent 1d5b256 commit a61de15

File tree

5 files changed

+141
-14
lines changed

5 files changed

+141
-14
lines changed

pkg/name/digest.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package name
1717
import (
1818
// nolint: depguard
1919
_ "crypto/sha256" // Recommended by go-digest.
20+
"encoding"
2021
"encoding/json"
2122
"strings"
2223

@@ -32,8 +33,11 @@ type Digest struct {
3233
original string
3334
}
3435

35-
// Ensure Digest implements Reference
3636
var _ Reference = (*Digest)(nil)
37+
var _ encoding.TextMarshaler = (*Digest)(nil)
38+
var _ encoding.TextUnmarshaler = (*Digest)(nil)
39+
var _ json.Marshaler = (*Digest)(nil)
40+
var _ json.Unmarshaler = (*Digest)(nil)
3741

3842
// Context implements Reference.
3943
func (d Digest) Context() Repository {
@@ -79,6 +83,21 @@ func (d *Digest) UnmarshalJSON(data []byte) error {
7983
return nil
8084
}
8185

86+
// MarshalText formats the digest into a string for text serialization.
87+
func (d Digest) MarshalText() ([]byte, error) {
88+
return []byte(d.String()), nil
89+
}
90+
91+
// UnmarshalText parses a text string into a Digest.
92+
func (d *Digest) UnmarshalText(data []byte) error {
93+
n, err := NewDigest(string(data))
94+
if err != nil {
95+
return err
96+
}
97+
*d = n
98+
return nil
99+
}
100+
82101
// NewDigest returns a new Digest representing the given name.
83102
func NewDigest(name string, opts ...Option) (Digest, error) {
84103
// Split on "@"

pkg/name/registry.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package name
1616

1717
import (
18+
"encoding"
19+
"encoding/json"
1820
"net"
1921
"net/url"
2022
"path"
@@ -37,6 +39,11 @@ type Registry struct {
3739
registry string
3840
}
3941

42+
var _ encoding.TextMarshaler = (*Registry)(nil)
43+
var _ encoding.TextUnmarshaler = (*Registry)(nil)
44+
var _ json.Marshaler = (*Registry)(nil)
45+
var _ json.Unmarshaler = (*Registry)(nil)
46+
4047
// RegistryStr returns the registry component of the Registry.
4148
func (r Registry) RegistryStr() string {
4249
return r.registry
@@ -140,3 +147,33 @@ func NewInsecureRegistry(name string, opts ...Option) (Registry, error) {
140147
opts = append(opts, Insecure)
141148
return NewRegistry(name, opts...)
142149
}
150+
151+
// MarshalJSON formats the Registry into a string for JSON serialization.
152+
func (r Registry) MarshalJSON() ([]byte, error) { return json.Marshal(r.String()) }
153+
154+
// UnmarshalJSON parses a JSON string into a Registry.
155+
func (r *Registry) UnmarshalJSON(data []byte) error {
156+
var s string
157+
if err := json.Unmarshal(data, &s); err != nil {
158+
return err
159+
}
160+
n, err := NewRegistry(s)
161+
if err != nil {
162+
return err
163+
}
164+
*r = n
165+
return nil
166+
}
167+
168+
// MarshalText formats the registry into a string for text serialization.
169+
func (r Registry) MarshalText() ([]byte, error) { return []byte(r.String()), nil }
170+
171+
// UnmarshalText parses a text string into a Registry.
172+
func (r *Registry) UnmarshalText(data []byte) error {
173+
n, err := NewRegistry(string(data))
174+
if err != nil {
175+
return err
176+
}
177+
*r = n
178+
return nil
179+
}

pkg/name/repository.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package name
1616

1717
import (
18+
"encoding"
19+
"encoding/json"
1820
"fmt"
1921
"strings"
2022
)
@@ -31,6 +33,11 @@ type Repository struct {
3133
repository string
3234
}
3335

36+
var _ encoding.TextMarshaler = (*Repository)(nil)
37+
var _ encoding.TextUnmarshaler = (*Repository)(nil)
38+
var _ json.Marshaler = (*Repository)(nil)
39+
var _ json.Unmarshaler = (*Repository)(nil)
40+
3441
// See https://docs.docker.com/docker-hub/official_repos
3542
func hasImplicitNamespace(repo string, reg Registry) bool {
3643
return !strings.ContainsRune(repo, '/') && reg.RegistryStr() == DefaultRegistry
@@ -119,3 +126,33 @@ func (r Repository) Digest(identifier string) Digest {
119126
d.original = d.Name()
120127
return d
121128
}
129+
130+
// MarshalJSON formats the Repository into a string for JSON serialization.
131+
func (r Repository) MarshalJSON() ([]byte, error) { return json.Marshal(r.String()) }
132+
133+
// UnmarshalJSON parses a JSON string into a Repository.
134+
func (r *Repository) UnmarshalJSON(data []byte) error {
135+
var s string
136+
if err := json.Unmarshal(data, &s); err != nil {
137+
return err
138+
}
139+
n, err := NewRepository(s)
140+
if err != nil {
141+
return err
142+
}
143+
*r = n
144+
return nil
145+
}
146+
147+
// MarshalText formats the repository name into a string for text serialization.
148+
func (r Repository) MarshalText() ([]byte, error) { return []byte(r.String()), nil }
149+
150+
// UnmarshalText parses a text string into a Repository.
151+
func (r *Repository) UnmarshalText(data []byte) error {
152+
n, err := NewRepository(string(data))
153+
if err != nil {
154+
return err
155+
}
156+
*r = n
157+
return nil
158+
}

pkg/name/tag.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package name
1616

1717
import (
18+
"encoding"
19+
"encoding/json"
1820
"strings"
1921
)
2022

@@ -31,8 +33,11 @@ type Tag struct {
3133
original string
3234
}
3335

34-
// Ensure Tag implements Reference
3536
var _ Reference = (*Tag)(nil)
37+
var _ encoding.TextMarshaler = (*Tag)(nil)
38+
var _ encoding.TextUnmarshaler = (*Tag)(nil)
39+
var _ json.Marshaler = (*Tag)(nil)
40+
var _ json.Unmarshaler = (*Tag)(nil)
3641

3742
// Context implements Reference.
3843
func (t Tag) Context() Repository {
@@ -106,3 +111,33 @@ func NewTag(name string, opts ...Option) (Tag, error) {
106111
original: name,
107112
}, nil
108113
}
114+
115+
// MarshalJSON formats the Tag into a string for JSON serialization.
116+
func (t Tag) MarshalJSON() ([]byte, error) { return json.Marshal(t.String()) }
117+
118+
// UnmarshalJSON parses a JSON string into a Tag.
119+
func (t *Tag) UnmarshalJSON(data []byte) error {
120+
var s string
121+
if err := json.Unmarshal(data, &s); err != nil {
122+
return err
123+
}
124+
n, err := NewTag(s)
125+
if err != nil {
126+
return err
127+
}
128+
*t = n
129+
return nil
130+
}
131+
132+
// MarshalText formats the tag into a string for text serialization.
133+
func (t Tag) MarshalText() ([]byte, error) { return []byte(t.String()), nil }
134+
135+
// UnmarshalText parses a text string into a Tag.
136+
func (t *Tag) UnmarshalText(data []byte) error {
137+
n, err := NewTag(string(data))
138+
if err != nil {
139+
return err
140+
}
141+
*t = n
142+
return nil
143+
}

pkg/v1/hash.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ package v1
1616

1717
import (
1818
"crypto"
19+
"encoding"
1920
"encoding/hex"
2021
"encoding/json"
2122
"fmt"
2223
"hash"
2324
"io"
24-
"strconv"
2525
"strings"
2626
)
2727

@@ -34,6 +34,11 @@ type Hash struct {
3434
Hex string
3535
}
3636

37+
var _ encoding.TextMarshaler = (*Hash)(nil)
38+
var _ encoding.TextUnmarshaler = (*Hash)(nil)
39+
var _ json.Marshaler = (*Hash)(nil)
40+
var _ json.Unmarshaler = (*Hash)(nil)
41+
3742
// String reverses NewHash returning the string-form of the hash.
3843
func (h Hash) String() string {
3944
return fmt.Sprintf("%s:%s", h.Algorithm, h.Hex)
@@ -49,30 +54,24 @@ func NewHash(s string) (Hash, error) {
4954
}
5055

5156
// MarshalJSON implements json.Marshaler
52-
func (h Hash) MarshalJSON() ([]byte, error) {
53-
return json.Marshal(h.String())
54-
}
57+
func (h Hash) MarshalJSON() ([]byte, error) { return json.Marshal(h.String()) }
5558

5659
// UnmarshalJSON implements json.Unmarshaler
5760
func (h *Hash) UnmarshalJSON(data []byte) error {
58-
s, err := strconv.Unquote(string(data))
59-
if err != nil {
61+
var s string
62+
if err := json.Unmarshal(data, &s); err != nil {
6063
return err
6164
}
6265
return h.parse(s)
6366
}
6467

6568
// MarshalText implements encoding.TextMarshaler. This is required to use
6669
// v1.Hash as a key in a map when marshalling JSON.
67-
func (h Hash) MarshalText() (text []byte, err error) {
68-
return []byte(h.String()), nil
69-
}
70+
func (h Hash) MarshalText() ([]byte, error) { return []byte(h.String()), nil }
7071

7172
// UnmarshalText implements encoding.TextUnmarshaler. This is required to use
7273
// v1.Hash as a key in a map when unmarshalling JSON.
73-
func (h *Hash) UnmarshalText(text []byte) error {
74-
return h.parse(string(text))
75-
}
74+
func (h *Hash) UnmarshalText(text []byte) error { return h.parse(string(text)) }
7675

7776
// Hasher returns a hash.Hash for the named algorithm (e.g. "sha256")
7877
func Hasher(name string) (hash.Hash, error) {

0 commit comments

Comments
 (0)