Blob


1 package mailmux
3 import (
4 "encoding/json"
5 "errors"
6 "io"
7 "time"
8 )
10 const (
11 Tregister = 1 + iota
12 Rregister
13 Rerror
14 Tnew
15 Rnew
16 Tlist
17 Rlist
18 Tremove
19 )
21 // Mcall represents a message passed between mailmux clients and servers.
22 // Operations requested by clients are T-messages (such as Tregister).
23 // Servers respond with the corresponding R-message (such as Rregister).
24 // Servers may instead respond with Rerror to inform the client, with a diagnostic message,
25 // that the request was not completed successfully.
26 // This design is loosely based on the Plan 9 network file protocol 9P.
27 type Mcall struct {
28 Type uint
29 Username string `json:",omitempty"` // Tregister, Rregister
30 Password string `json:",omitempty"` // Tregister
31 Error string `json:",omitempty"` // Rerror
32 Aliases []Alias `json:",omitempty"` // Rnew, Rlist, Tremove
33 Expiry time.Time `json:",omitempty"` // Tnew, Rnew
34 }
36 // ParseMcall parses and validates a JSON-encoded Mcall from r.
37 func ParseMcall(r io.Reader) (*Mcall, error) {
38 var mc Mcall
39 if err := json.NewDecoder(r).Decode(&mc); err != nil {
40 return nil, err
41 }
42 switch mc.Type {
43 case Rerror:
44 if mc.Error == "" {
45 return nil, errors.New("empty error message")
46 }
47 case Tregister, Tnew, Tlist, Tremove:
48 if mc.Username == "" {
49 return nil, errors.New("empty username")
50 } else if mc.Password == "" {
51 return nil, errors.New("empty password")
52 }
53 }
54 return &mc, nil
55 }