Files

70 lines
1.4 KiB
Go

package wire
import (
"encoding/json"
"fmt"
decimal "github.com/alpacahq/alpacadecimal"
)
// Unwrap returns the inner JSON of an optional {"data": ...} envelope.
func Unwrap(raw json.RawMessage) json.RawMessage {
if len(raw) == 0 {
return raw
}
var wrap struct {
Data json.RawMessage `json:"data"`
}
if json.Unmarshal(raw, &wrap) == nil && len(wrap.Data) > 0 {
return wrap.Data
}
return raw
}
// Dec parses a required money/size/price value.
func Dec(v any) (decimal.Decimal, error) {
switch x := v.(type) {
case nil:
return decimal.Zero, nil
case float64:
return decimal.NewFromFloat(x), nil
case json.Number:
d, err := decimal.NewFromString(string(x))
if err != nil {
return decimal.Zero, fmt.Errorf("parse decimal: %v", v)
}
return d, nil
case string:
if x == "" {
return decimal.Zero, nil
}
d, err := decimal.NewFromString(x)
if err != nil {
return decimal.Zero, fmt.Errorf("parse decimal: %v", v)
}
return d, nil
default:
return decimal.Zero, fmt.Errorf("parse decimal: %v", v)
}
}
// DecOpt parses an optional money/size/price value.
func DecOpt(v any) (*decimal.Decimal, error) {
if v == nil {
return nil, nil
}
if s, ok := v.(string); ok && s == "" {
return nil, nil
}
d, err := Dec(v)
if err != nil {
return nil, err
}
return &d, nil
}
// Encode is Decimal.String for Robinhood string wire fields.
func Encode(d decimal.Decimal) string {
return d.String()
}