-
Notifications
You must be signed in to change notification settings - Fork 1
/
serde.go
150 lines (127 loc) · 7.15 KB
/
serde.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package dec
import (
"errors"
"fmt"
)
type (
TextDeci Decimal
TextCenti Decimal
TextMilli Decimal
TextMicro Decimal
TextNano Decimal
TextPico Decimal
TextFemto Decimal
TextAtto Decimal
TextZepto Decimal
TextYocto Decimal
TextRonto Decimal
TextQuecto Decimal
)
var ErrTypePrecisionMismatch = errors.New("decimal value and type precisions mismatch")
type typePrecisionWrapper interface {
TypePrecision() Precision
GetDecimal() Decimal
SetDecimal(d Decimal)
}
func marshalText[T typePrecisionWrapper](d T) ([]byte, error) {
value := d.GetDecimal()
if value.Precision() != d.TypePrecision() {
return nil, ErrTypePrecisionMismatch
}
return []byte(fmt.Sprintf("%q", value.String())), nil
}
func unmarshalText[T typePrecisionWrapper](d *T, data []byte) error {
if len(data) < 1 {
return errors.New("invalid decimal number")
}
coins, err := Parse(string(data), (*d).TypePrecision(), true)
if err != nil {
return err
}
(*d).SetDecimal(coins)
return nil
}
type DecimalTextTrait interface {
TextDeci | TextCenti |
TextMilli | TextMicro |
TextNano | TextPico |
TextFemto | TextAtto |
TextZepto | TextYocto |
TextRonto | TextQuecto
}
func ref[T DecimalTextTrait](d Decimal) *T {
v := T(d)
return &v
}
func TextDeciRef(d Decimal) *TextDeci { return ref[TextDeci](d) }
func (_ *TextDeci) TypePrecision() Precision { return Deci }
func (d *TextDeci) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextDeci) SetDecimal(v Decimal) { *d = TextDeci(v) }
func (d *TextDeci) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextDeci) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextCentiRef(d Decimal) *TextCenti { return ref[TextCenti](d) }
func (_ *TextCenti) TypePrecision() Precision { return Centi }
func (d *TextCenti) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextCenti) SetDecimal(v Decimal) { *d = TextCenti(v) }
func (d *TextCenti) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextCenti) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextMilliRef(d Decimal) *TextMilli { return ref[TextMilli](d) }
func (_ *TextMilli) TypePrecision() Precision { return Milli }
func (d *TextMilli) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextMilli) SetDecimal(v Decimal) { *d = TextMilli(v) }
func (d *TextMilli) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextMilli) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextMicroRef(d Decimal) *TextMicro { return ref[TextMicro](d) }
func (_ *TextMicro) TypePrecision() Precision { return Micro }
func (d *TextMicro) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextMicro) SetDecimal(v Decimal) { *d = TextMicro(v) }
func (d *TextMicro) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextMicro) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextNanoRef(d Decimal) *TextNano { return ref[TextNano](d) }
func (_ *TextNano) TypePrecision() Precision { return Nano }
func (d *TextNano) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextNano) SetDecimal(v Decimal) { *d = TextNano(v) }
func (d *TextNano) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextNano) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextPicoRef(d Decimal) *TextPico { return ref[TextPico](d) }
func (_ *TextPico) TypePrecision() Precision { return Pico }
func (d *TextPico) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextPico) SetDecimal(v Decimal) { *d = TextPico(v) }
func (d *TextPico) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextPico) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextFemtoRef(d Decimal) *TextFemto { return ref[TextFemto](d) }
func (_ *TextFemto) TypePrecision() Precision { return Femto }
func (d *TextFemto) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextFemto) SetDecimal(v Decimal) { *d = TextFemto(v) }
func (d *TextFemto) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextFemto) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextAttoRef(d Decimal) *TextAtto { return ref[TextAtto](d) }
func (_ *TextAtto) TypePrecision() Precision { return Atto }
func (d *TextAtto) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextAtto) SetDecimal(v Decimal) { *d = TextAtto(v) }
func (d *TextAtto) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextAtto) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextZeptoRef(d Decimal) *TextZepto { return ref[TextZepto](d) }
func (_ *TextZepto) TypePrecision() Precision { return Zepto }
func (d *TextZepto) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextZepto) SetDecimal(v Decimal) { *d = TextZepto(v) }
func (d *TextZepto) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextZepto) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextYoctoRef(d Decimal) *TextYocto { return ref[TextYocto](d) }
func (_ *TextYocto) TypePrecision() Precision { return Yocto }
func (d *TextYocto) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextYocto) SetDecimal(v Decimal) { *d = TextYocto(v) }
func (d *TextYocto) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextYocto) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextRontoRef(d Decimal) *TextRonto { return ref[TextRonto](d) }
func (_ *TextRonto) TypePrecision() Precision { return Ronto }
func (d *TextRonto) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextRonto) SetDecimal(v Decimal) { *d = TextRonto(v) }
func (d *TextRonto) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextRonto) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }
func TextQuectoRef(d Decimal) *TextQuecto { return ref[TextQuecto](d) }
func (_ *TextQuecto) TypePrecision() Precision { return Quecto }
func (d *TextQuecto) GetDecimal() Decimal { return Decimal(*d) }
func (d *TextQuecto) SetDecimal(v Decimal) { *d = TextQuecto(v) }
func (d *TextQuecto) MarshalText() ([]byte, error) { return marshalText(d) }
func (d *TextQuecto) UnmarshalText(data []byte) (err error) { return unmarshalText(&d, data) }