Blob


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