response.go 1.51 KB
Newer Older
Matt Bell's avatar
Matt Bell committed
1 2
package commands

3 4 5 6 7 8 9
import (
  "fmt"
  "strings"
  "encoding/json"
  "encoding/xml"
)

Matt Bell's avatar
Matt Bell committed
10 11 12 13 14 15 16
type ErrorType uint
const (
  Normal ErrorType = iota // general errors
  Client // error was caused by the client, (e.g. invalid CLI usage)
  // TODO: add more types of errors for better error-specific handling
)

17 18
// Error is a struct for marshalling errors
type Error struct {
19 20
  Message string
  Code ErrorType
21 22
}

23 24 25 26 27 28 29 30 31 32 33 34 35
type EncodingType string
const (
  Json = "json"
  Xml = "xml"
  // TODO: support more encoding types
)

type Marshaller func(v interface{})([]byte, error)
var marshallers = map[EncodingType]Marshaller{
  Json: json.Marshal,
  Xml: xml.Marshal,
}

Matt Bell's avatar
Matt Bell committed
36 37 38 39 40 41 42 43 44 45 46 47
type Response struct {
  req *Request
  Error error
  ErrorType ErrorType
  Value interface{}
}

func (r *Response) SetError(err error, errType ErrorType) {
  r.Error = err
  r.ErrorType = errType
}

48 49 50 51
func (r *Response) FormatError() Error {
  return Error{ r.Error.Error(), r.ErrorType }
}

52
func (r *Response) Marshal() ([]byte, error) {
53 54 55 56
  if r.Error == nil && r.Value == nil {
    return nil, fmt.Errorf("No error or value set, there is nothing to marshal")
  }

57 58 59 60 61
  enc := r.req.Option("enc")
  if enc == nil {
    return nil, fmt.Errorf("No encoding type was specified")
  }
  encType := EncodingType(strings.ToLower(enc.(string)))
Matt Bell's avatar
Matt Bell committed
62

63 64 65 66 67
  marshaller, ok := marshallers[encType]
  if !ok {
    return nil, fmt.Errorf("No marshaller found for encoding type '%s'", enc)
  }

68 69 70 71 72 73
  if r.Error != nil {
    err := r.FormatError()
    return marshaller(err)
  } else {
    return marshaller(r.Value)
  }
74
}