Blob


1 package mailmux
3 import (
4 "encoding/json"
5 "errors"
6 "fmt"
7 "net"
8 )
10 const apiurl = "https://mailmux.net/v1/aliases"
12 const jsonContentType = "application/json"
14 type Client struct {
15 conn net.Conn // or io.ReadWriteCloser?
16 }
18 func Dial(network, address string) (*Client, error) {
19 c, err := net.Dial(network, address)
20 if err != nil {
21 return nil, err
22 }
23 return &Client{conn: c}, nil
24 }
26 func (c *Client) exchange(tmsg *Mcall) (*Mcall, error) {
27 if err := c.tx(tmsg); err != nil {
28 return nil, fmt.Errorf("transmit tmsg: %w", err)
29 }
30 rmsg, err := c.rx()
31 if err != nil {
32 return nil, fmt.Errorf("receive rmsg: %w", err)
33 }
34 // TODO sanity checks here.
35 // did we get back the message type we expected?
36 return rmsg, nil
37 }
39 func (c *Client) tx(tmsg *Mcall) error {
40 return json.NewEncoder(c.conn).Encode(tmsg)
41 }
43 func (c *Client) rx() (*Mcall, error) {
44 return ParseMcall(c.conn)
45 }
47 func (c *Client) Auth(username, password string) error {
48 tmsg := &Mcall{
49 Type: Tauth,
50 Username: username,
51 Password: password,
52 }
53 rmsg, err := c.exchange(tmsg)
54 if err != nil {
55 return err
56 }
57 if rmsg.Type == Rerror {
58 return errors.New(rmsg.Error)
59 }
60 return nil
61 }
63 func (c *Client) NewAlias() ([]Alias, error) {
64 tmsg := &Mcall{
65 Type: Tcreate,
66 }
67 rmsg, err := c.exchange(tmsg)
68 if err != nil {
69 return nil, fmt.Errorf("exchange tmsg: %w", err)
70 }
71 if rmsg.Type == Rerror {
72 return nil, errors.New(rmsg.Error)
73 }
74 return rmsg.Aliases, nil
75 }
77 func (c *Client) Aliases() ([]Alias, error) {
78 tmsg := &Mcall{
79 Type: Tlist,
80 }
81 rmsg, err := c.exchange(tmsg)
82 if err != nil {
83 return nil, fmt.Errorf("exchange tmsg: %w", err)
84 }
85 if rmsg.Type == Rerror {
86 return nil, errors.New(rmsg.Error)
87 }
88 return rmsg.Aliases, nil
89 }
91 func (c *Client) Close() error {
92 return c.conn.Close()
93 }