func (c *Conn) Cmd(cmd string, isMulti bool, args ...interface{}) (*bytes.Buffer, error) {
	var cmdLine string
	if len(args) > 0 {
		format := " " + strings.TrimRight(strings.Repeat("%v ", len(args)), " ")
		cmdLine = fmt.Sprintf(cmd+format, args...)
	} else {
		cmdLine = cmd
	}
	if err := c.Send(cmdLine); err != nil {
		return nil, err
	}
	b, err := c.ReadOne()
	if err != nil {
		return nil, err
	}
	if !isMulti {
		return bytes.NewBuffer(b), err
	}
	buf, err := c.ReadAll()
	return buf, err
}
Cmd sends a command to the server. POP3 responses are either single line or multi-line.
The first line always with -ERR in case of an error or +OK in case of a successful operation.
OK+ is always followed by a response on the same line which is either the actual response data
in case of single line responses, or a help message followed by multiple lines of actual response
data in case of multiline responses.
See https://www.shellhacks.com/retrieve-email-pop3-server-command-line/ for examples.
package pop3
import (
	"bufio"
	"bytes"
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"strconv"
	"strings"
	"time"
	"github.com/emersion/go-message"
)
type Client struct {
	opt Opt
}
type Conn struct {
	conn net.Conn
	r    *bufio.Reader
	w    *bufio.Writer
}
type Opt struct {
	Host string `json:"host"`
	Port int    `json:"port"`
	DialTimeout time.Duration `json:"dial_timeout"`
	TLSEnabled    bool `json:"tls_enabled"`
	TLSSkipVerify bool `json:"tls_skip_verify"`
}
type MessageID struct {
	ID   int
	Size int
	UID string
}
var (
	lineBreak = []byte("\r\n")
	respOK      = []byte("+OK")    
	respOKInfo  = []byte("+OK ")   
	respErr     = []byte("-ERR")   
	respErrInfo = []byte("-ERR ")  
)
func New(opt Opt) *Client {
	if opt.DialTimeout < time.Millisecond {
		opt.DialTimeout = time.Second * 3
	}
	return &Client{
		opt: opt,
	}
}
func (c *Client) NewConn() (*Conn, error) {
	var (
		addr = fmt.Sprintf("%s:%d", c.opt.Host, c.opt.Port)
	)
	conn, err := net.DialTimeout("tcp", addr, c.opt.DialTimeout)
	if err != nil {
		return nil, err
	}
	if c.opt.TLSEnabled {
		tlsCfg := tls.Config{}
		if c.opt.TLSSkipVerify {
			tlsCfg.InsecureSkipVerify = c.opt.TLSSkipVerify
		} else {
			tlsCfg.ServerName = c.opt.Host
		}
		conn = tls.Client(conn, &tlsCfg)
	}
	pCon := &Conn{
		conn: conn,
		r:    bufio.NewReader(conn),
		w:    bufio.NewWriter(conn),
	}
	if _, err := pCon.ReadOne(); err != nil {
		return nil, err
	}
	return pCon, nil
}
func (c *Conn) Send(b string) error {
	if _, err := c.w.WriteString(b + "\r\n"); err != nil {
		return err
	}
	return c.w.Flush()
}