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 }