@@ -9,6 +9,13 @@ import (
9
9
"strings"
10
10
)
11
11
12
+ // available errors
13
+ var (
14
+ UnsupportedFormat = errors .New ("unsupported data size format" )
15
+ UnexpectedError = errors .New ("unable convert" )
16
+ )
17
+
18
+ // regexp parsing string expression
12
19
const (
13
20
measurePattern string = `^([bB]|[bB]ytes|[kmgtpeKMGTPE]|[kmgtpeKMGTPE]?[iI]|[kmgtpeKMGTPE][iI]?[bB])?$`
14
21
sizePattern string = `^([0-9]+|[0-9]*\.[0-9]+)([bB]|[bB]ytes|[kmgtpeKMGTPE]|[kmgtpeKMGTPE]?[iI]|[kmgtpeKMGTPE][iI]?[bB])?$`
@@ -40,13 +47,21 @@ func (rs *ReadableSize) GetRaw() big.Float {
40
47
41
48
// Get returns the compiled data size in big.Int.
42
49
func (rs * ReadableSize ) Get () big.Int {
50
+ if rs .compiled == nil {
51
+ return * big .NewInt (0 )
52
+ }
53
+
43
54
res , _ := rs .compiled .Int (new (big.Int ))
44
55
return * res
45
56
}
46
57
47
58
// GetCompiledUInt64 returns the compiled data size in uint64.
48
59
// Warning: Possible rounding overflow, use with relatively small numbers.
49
60
func (rs * ReadableSize ) GetCompiledUInt64 () uint64 {
61
+ if rs .compiled == nil {
62
+ return 0
63
+ }
64
+
50
65
res , _ := rs .compiled .Uint64 ()
51
66
return res
52
67
}
@@ -62,7 +77,56 @@ func (rs *ReadableSize) GetCompiledInMeasure(measure string) (float64, error) {
62
77
return tmp , nil
63
78
}
64
79
65
- return 0 , errors .New ("unsupported measure format" )
80
+ return 0 , UnsupportedFormat
81
+ }
82
+
83
+ // UnmarshalJSON designed to serialize a string in data size expression to *ReadableSize, defined in user code via the json library
84
+ func (rs * ReadableSize ) UnmarshalJSON (source []byte ) error {
85
+ value := string (source )
86
+
87
+ if len (value ) < 2 {
88
+ return UnsupportedFormat
89
+ }
90
+
91
+ if value == "null" {
92
+ return nil
93
+ }
94
+
95
+ if parsed , err := Compile (value [1 : len (value )- 1 ]); err == nil {
96
+ * rs = * parsed
97
+ return nil
98
+ } else {
99
+ return err
100
+ }
101
+ }
102
+
103
+ // MarshalJSON designed to deserialize *ReadableSize to original data size expression defined in user code via the json library
104
+ func (rs ReadableSize ) MarshalJSON () ([]byte , error ) {
105
+ return []byte ("\" " + rs .input + "\" " ), nil
106
+ }
107
+
108
+ // UnmarshalYAML designed to serialize a string in data size expression to *ReadableSize, defined in user code via the gopkg.in/yaml.v3 library
109
+ func (rs * ReadableSize ) UnmarshalYAML (unmarshal func (interface {}) error ) error {
110
+ var str string
111
+ if err := unmarshal (& str ); err != nil {
112
+ return UnsupportedFormat
113
+ }
114
+
115
+ if str == "null" {
116
+ return nil
117
+ }
118
+
119
+ if parsed , err := Compile (str ); err == nil {
120
+ * rs = * parsed
121
+ return nil
122
+ } else {
123
+ return err
124
+ }
125
+ }
126
+
127
+ // MarshalYAML designed to deserialize *ReadableSize in original data size expression defined in user code via the gopkg.in/yaml.v3 library
128
+ func (rs ReadableSize ) MarshalYAML () (interface {}, error ) {
129
+ return rs .input , nil
66
130
}
67
131
68
132
// compileMeasuring returns a numeric representation of a data unit in int64.
@@ -110,7 +174,7 @@ func Compile(input string) (*ReadableSize, error) {
110
174
}
111
175
}
112
176
113
- return nil , errors . New ( "unsupported data size format" )
177
+ return nil , UnsupportedFormat
114
178
}
115
179
116
180
// MustCompile parses a data size expression and returns, if successful,
@@ -154,5 +218,5 @@ func BytesToSize(size float64, precision uint) (string, error) {
154
218
size /= 1 << 10
155
219
}
156
220
157
- return "" , errors . New ( "unable convert" )
221
+ return "" , UnexpectedError
158
222
}
0 commit comments