70 lines
1.4 KiB
Go
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()
|
|
}
|