types/empty: add Message, stop using mysterious *struct{}

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2020-02-14 13:09:19 -08:00 committed by Brad Fitzpatrick
parent 4796f6fd67
commit 747c7d7ce2
5 changed files with 33 additions and 15 deletions

View File

@ -21,6 +21,7 @@ import (
"tailscale.com/logger"
"tailscale.com/logtail/backoff"
"tailscale.com/tailcfg"
"tailscale.com/types/empty"
)
// TODO(apenwarr): eliminate the 'state' variable, as it's now obsolete.
@ -60,7 +61,7 @@ func (s state) String() string {
}
type Status struct {
LoginFinished *struct{}
LoginFinished *empty.Message
Err string
URL string
Persist *Persist // locally persisted configuration
@ -507,9 +508,9 @@ func (c *Client) sendStatus(who string, err error, url string, nm *NetworkMap) {
c.logf("sendStatus: %s: %v\n", who, state)
var p *Persist
var fin *struct{}
var fin *empty.Message
if state == stateAuthenticated {
fin = &struct{}{}
fin = new(empty.Message)
}
if nm != nil && loggedIn && synced {
pp := c.direct.GetPersist()

View File

@ -7,6 +7,8 @@ package controlclient
import (
"reflect"
"testing"
"tailscale.com/types/empty"
)
func fieldsOf(t reflect.Type) (fields []string) {
@ -55,7 +57,7 @@ func TestStatusEqual(t *testing.T) {
},
{
&Status{LoginFinished: nil},
&Status{LoginFinished: new(struct{})},
&Status{LoginFinished: new(empty.Message)},
false,
},
}

View File

@ -9,6 +9,7 @@ import (
"tailscale.com/control/controlclient"
"tailscale.com/tailcfg"
"tailscale.com/types/empty"
"tailscale.com/wgengine"
)
@ -39,15 +40,15 @@ type NetworkMap = controlclient.NetworkMap
// In any given notification, any or all of these may be nil, meaning
// that they have not changed.
type Notify struct {
Version string // version number of IPN backend
ErrMessage *string // critical error message, if any
LoginFinished *struct{} // event: login process succeeded
State *State // current IPN state has changed
Prefs *Prefs // preferences were changed
NetMap *NetworkMap // new netmap received
Engine *EngineStatus // wireguard engine stats
BrowseToURL *string // UI should open a browser right now
BackendLogID *string // public logtail id used by backend
Version string // version number of IPN backend
ErrMessage *string // critical error message, if any
LoginFinished *empty.Message // event: non-nil when login process succeeded
State *State // current IPN state has changed
Prefs *Prefs // preferences were changed
NetMap *NetworkMap // new netmap received
Engine *EngineStatus // wireguard engine stats
BrowseToURL *string // UI should open a browser right now
BackendLogID *string // public logtail id used by backend
}
// StateKey is an opaque identifier for a set of LocalBackend state

View File

@ -17,6 +17,7 @@ import (
"tailscale.com/logger"
"tailscale.com/portlist"
"tailscale.com/tailcfg"
"tailscale.com/types/empty"
"tailscale.com/version"
"tailscale.com/wgengine"
"tailscale.com/wgengine/filter"
@ -194,8 +195,7 @@ func (b *LocalBackend) Start(opts Options) error {
// Auth completed, unblock the engine
b.blockEngineUpdates(false)
b.authReconfig()
noargs := struct{}{}
b.send(Notify{LoginFinished: &noargs})
b.send(Notify{LoginFinished: &empty.Message{}})
}
if new.Persist != nil {
persist := *new.Persist // copy

14
types/empty/message.go Normal file
View File

@ -0,0 +1,14 @@
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package empty defines an empty struct type.
package empty
// Message is an empty message. Its purpose is to be used as pointer
// type where nil and non-nil distinguish whether it's set. This is
// used instead of a bool when we want to marshal it as a JSON empty
// object (or null) for the future ability to add other fields, at
// which point callers would define a new struct and not use
// empty.Message.
type Message struct{}