github.com/bitfinexcom/bitfinex-api-go@v0.0.0-20210608095005-9e0b26f200fb/pkg/mux/msg/msg.go (about)

     1  package msg
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"unicode"
     9  
    10  	"github.com/bitfinexcom/bitfinex-api-go/pkg/convert"
    11  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/balanceinfo"
    12  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/book"
    13  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/candle"
    14  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/event"
    15  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingcredit"
    16  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingloan"
    17  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingoffer"
    18  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundingtrade"
    19  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/margin"
    20  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/notification"
    21  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/order"
    22  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/position"
    23  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/status"
    24  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/ticker"
    25  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/trades"
    26  	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/wallet"
    27  )
    28  
    29  type Msg struct {
    30  	Data     []byte
    31  	Err      error
    32  	CID      int
    33  	IsPublic bool
    34  }
    35  
    36  func (m Msg) IsEvent() bool {
    37  	t := bytes.TrimLeftFunc(m.Data, unicode.IsSpace)
    38  	return bytes.HasPrefix(t, []byte("{"))
    39  }
    40  
    41  func (m Msg) IsRaw() bool {
    42  	t := bytes.TrimLeftFunc(m.Data, unicode.IsSpace)
    43  	return bytes.HasPrefix(t, []byte("["))
    44  }
    45  
    46  // PreprocessRaw takes raw slice of bytes and splits it into:
    47  // 1. raw payload data - always last element of the slice
    48  // 2. chanID - always 1st element of the slice
    49  // 3. msg type - in 3 element msg slice, type is always at index 1
    50  func (m Msg) PreprocessRaw() (raw []interface{}, pld interface{}, chID int64, msgType string, err error) {
    51  	err = json.Unmarshal(m.Data, &raw)
    52  	pld = raw[len(raw)-1]
    53  	chID = convert.I64ValOrZero(raw[0])
    54  	if len(raw) == 3 {
    55  		msgType = convert.SValOrEmpty(raw[1])
    56  	}
    57  	return
    58  }
    59  
    60  func (m Msg) ProcessPublic(raw []interface{}, pld interface{}, chID int64, inf event.Info) (interface{}, error) {
    61  	switch data := pld.(type) {
    62  	case string:
    63  		return event.Info{
    64  			ChanID:    chID,
    65  			Subscribe: event.Subscribe{Event: data},
    66  		}, nil
    67  	case []interface{}:
    68  		switch inf.Channel {
    69  		case "trades":
    70  			return trades.FromWSRaw(inf.Symbol, raw, data)
    71  		case "ticker":
    72  			return ticker.FromWSRaw(inf.Symbol, data)
    73  		case "book":
    74  			return book.FromWSRaw(inf.Symbol, inf.Precision, data)
    75  		case "candles":
    76  			return candle.FromWSRaw(inf.Key, data)
    77  		case "status":
    78  			return status.FromWSRaw(inf.Key, data)
    79  		}
    80  	}
    81  
    82  	return raw, nil
    83  }
    84  
    85  func (m Msg) ProcessPrivate(raw []interface{}, pld interface{}, chID int64, op string) (interface{}, error) {
    86  	switch data := pld.(type) {
    87  	case string:
    88  		return event.Info{
    89  			ChanID:    chID,
    90  			Subscribe: event.Subscribe{Event: data},
    91  		}, nil
    92  	case []interface{}:
    93  		switch op {
    94  		case "bu":
    95  			return balanceinfo.UpdateFromRaw(data)
    96  		case "ps":
    97  			return position.SnapshotFromRaw(data)
    98  		case "pn":
    99  			return position.NewFromRaw(data)
   100  		case "pu":
   101  			return position.UpdateFromRaw(data)
   102  		case "pc":
   103  			return position.CancelFromRaw(data)
   104  		case "ws":
   105  			return wallet.SnapshotFromRaw(data)
   106  		case "wu":
   107  			return wallet.UpdateFromRaw(data)
   108  		case "os":
   109  			return order.SnapshotFromRaw(data)
   110  		case "on":
   111  			return order.NewFromRaw(data)
   112  		case "ou":
   113  			return order.UpdateFromRaw(data)
   114  		case "oc":
   115  			return order.CancelFromRaw(data)
   116  		case "te":
   117  			return trades.ATEFromRaw(data)
   118  		case "tu":
   119  			return trades.ATEUFromRaw(data)
   120  		case "fte":
   121  			return trades.AFTEFromRaw(data)
   122  		case "ftu":
   123  			return trades.AFTUFromRaw(data)
   124  		case "mis":
   125  			return nil, errors.New("mis msg type no longer supported")
   126  		case "miu":
   127  			return margin.FromRaw(data)
   128  		case "n":
   129  			return notification.FromRaw(data)
   130  		case "fos":
   131  			return fundingoffer.SnapshotFromRaw(data)
   132  		case "fon":
   133  			return fundingoffer.NewFromRaw(data)
   134  		case "fou":
   135  			return fundingoffer.UpdateFromRaw(data)
   136  		case "foc":
   137  			return fundingoffer.CancelFromRaw(data)
   138  		case "fcs":
   139  			return fundingcredit.SnapshotFromRaw(data)
   140  		case "fcn":
   141  			return fundingcredit.NewFromRaw(data)
   142  		case "fcu":
   143  			return fundingcredit.UpdateFromRaw(data)
   144  		case "fcc":
   145  			return fundingcredit.CancelFromRaw(data)
   146  		case "fls":
   147  			return fundingloan.SnapshotFromRaw(data)
   148  		case "fln":
   149  			return fundingloan.NewFromRaw(data)
   150  		case "flu":
   151  			return fundingloan.UpdateFromRaw(data)
   152  		case "flc":
   153  			return fundingloan.CancelFromRaw(data)
   154  		case "hfts":
   155  			return fundingtrade.HistoricalSnapshotFromRaw(data)
   156  		case "uac":
   157  			return nil, errors.New("uac msg type no longer supported")
   158  		}
   159  	}
   160  
   161  	return raw, nil
   162  }
   163  
   164  func (m Msg) ProcessEvent() (i event.Info, err error) {
   165  	if err = json.Unmarshal(m.Data, &i); err != nil {
   166  		return i, fmt.Errorf("parsing msg: %s, err: %s", m.Data, err)
   167  	}
   168  	return
   169  }