Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: logdog/common/types/streamaddr.go

Issue 2899993002: [logdog/common/types] custom JSON encoding to allow streamaddr to be zero. (Closed)
Patch Set: support embedded struct Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | logdog/common/types/streamaddr_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The LUCI Authors. All rights reserved. 1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 package types 5 package types
6 6
7 import ( 7 import (
8 "bytes"
9 "encoding/json"
8 "flag" 10 "flag"
9 "net/url" 11 "net/url"
10 "strings" 12 "strings"
11 13
12 "github.com/luci/luci-go/common/errors" 14 "github.com/luci/luci-go/common/errors"
13 "github.com/luci/luci-go/luci_config/common/cfgtypes" 15 "github.com/luci/luci-go/luci_config/common/cfgtypes"
14 ) 16 )
15 17
16 const logDogURLScheme = "logdog" 18 const logDogURLScheme = "logdog"
17 19
18 // StreamAddr is a fully-qualified LogDog stream address. 20 // StreamAddr is a fully-qualified LogDog stream address.
19 type StreamAddr struct { 21 type StreamAddr struct {
20 // Host is the LogDog host. 22 // Host is the LogDog host.
21 » Host string 23 » Host string `json:"host"`
22 24
23 // Project is the LUCI project name that this log belongs to. 25 // Project is the LUCI project name that this log belongs to.
24 » Project cfgtypes.ProjectName 26 » Project cfgtypes.ProjectName `json:"project"`
25 27
26 // Path is the LogDog stream path. 28 // Path is the LogDog stream path.
27 » Path StreamPath 29 » Path StreamPath `json:"path"`
28 } 30 }
29 31
30 var _ flag.Value = (*StreamAddr)(nil) 32 var _ flag.Value = (*StreamAddr)(nil)
31 33
32 // Set implements flag.Value 34 // Set implements flag.Value
33 func (s *StreamAddr) Set(v string) error { 35 func (s *StreamAddr) Set(v string) error {
34 a, err := ParseURL(v) 36 a, err := ParseURL(v)
35 if err != nil { 37 if err != nil {
36 return err 38 return err
37 } 39 }
(...skipping 25 matching lines...) Expand all
63 65
64 // URL returns a LogDog URL that represents this Stream. 66 // URL returns a LogDog URL that represents this Stream.
65 func (s *StreamAddr) URL() *url.URL { 67 func (s *StreamAddr) URL() *url.URL {
66 return &url.URL{ 68 return &url.URL{
67 Scheme: logDogURLScheme, 69 Scheme: logDogURLScheme,
68 Host: s.Host, 70 Host: s.Host,
69 Path: strings.Join([]string{"", string(s.Project), string(s.Pa th)}, "/"), 71 Path: strings.Join([]string{"", string(s.Project), string(s.Pa th)}, "/"),
70 } 72 }
71 } 73 }
72 74
75 // jsonStreamAddr is used to allow type checking during deserialization, but
76 // special casing IsZero == 'null'.
77 type jsonStreamAddr struct {
dnj 2017/05/23 15:28:19 This is unfortunate. Are you opposed to using "omi
78 Host string `json:"host"`
79 Project cfgtypes.ProjectName `json:"project"`
80 Path StreamPath `json:"path"`
81 }
82
83 // MarshalJSON implements json.Marshaler
84 func (s StreamAddr) MarshalJSON() ([]byte, error) {
85 if s.IsZero() {
86 return []byte(`null`), nil
87 }
88 // TODO(iannucci): when we support go 1.8 on appengine, this can be writ ten as
89 // json.Marshal((*jsonStreamAddr)(s)).
90 jsa := jsonStreamAddr{s.Host, s.Project, s.Path}
91 return json.Marshal(jsa)
92 }
93
94 // UnmarshalJSON implements json.Marshaler
95 func (s *StreamAddr) UnmarshalJSON(d []byte) error {
96 if bytes.Equal(d, []byte(`null`)) {
97 s.Host = ""
98 s.Project = ""
99 s.Path = ""
100 return nil
101 }
102 // TODO(iannucci): when we support go 1.8 on appengine, this can be writ ten as
103 // return json.Unmarshal(d, (*jsonStreamAddr)(s))
104 jsa := jsonStreamAddr{}
105 if err := json.Unmarshal(d, &jsa); err != nil {
106 return err
107 }
108 s.Host = jsa.Host
109 s.Project = jsa.Project
110 s.Path = jsa.Path
111 return nil
112 }
113
73 // ParseURL parses a LogDog URL into a Stream. If the URL is malformed, or 114 // ParseURL parses a LogDog URL into a Stream. If the URL is malformed, or
74 // if the host, project, or path is invalid, an error will be returned. 115 // if the host, project, or path is invalid, an error will be returned.
75 // 116 //
76 // A LogDog URL has the form: 117 // A LogDog URL has the form:
77 // logdog://<host>/<project>/<prefix>/+/<name> 118 // logdog://<host>/<project>/<prefix>/+/<name>
78 func ParseURL(v string) (*StreamAddr, error) { 119 func ParseURL(v string) (*StreamAddr, error) {
79 u, err := url.Parse(v) 120 u, err := url.Parse(v)
80 if err != nil { 121 if err != nil {
81 return nil, errors.Annotate(err).Reason("failed to parse URL").E rr() 122 return nil, errors.Annotate(err).Reason("failed to parse URL").E rr()
82 } 123 }
(...skipping 23 matching lines...) Expand all
106 } 147 }
107 148
108 if err := addr.Path.Validate(); err != nil { 149 if err := addr.Path.Validate(); err != nil {
109 return nil, errors.Annotate(err).Reason("invalid stream path: %( path)q"). 150 return nil, errors.Annotate(err).Reason("invalid stream path: %( path)q").
110 D("path", addr.Path). 151 D("path", addr.Path).
111 Err() 152 Err()
112 } 153 }
113 154
114 return &addr, nil 155 return &addr, nil
115 } 156 }
OLDNEW
« no previous file with comments | « no previous file | logdog/common/types/streamaddr_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698