@@ -135,6 +135,33 @@ func ValueOrDefault(intOrPercent *IntOrString, defaultValue IntOrString) *IntOrS
135
135
return intOrPercent
136
136
}
137
137
138
+ // GetScaledValueFromIntOrPercent is meant to replace GetValueFromIntOrPercent.
139
+ // This method returns a scaled value from an IntOrString type. If the IntOrString
140
+ // is a percentage string value it's treated as a percentage and scaled appropriately
141
+ // in accordance to the total, if it's an int value it's treated as a a simple value and
142
+ // if it is a string value which is either non-numeric or numeric but lacking a trailing '%' it returns an error.
143
+ func GetScaledValueFromIntOrPercent (intOrPercent * IntOrString , total int , roundUp bool ) (int , error ) {
144
+ if intOrPercent == nil {
145
+ return 0 , errors .New ("nil value for IntOrString" )
146
+ }
147
+ value , isPercent , err := getIntOrPercentValueSafely (intOrPercent )
148
+ if err != nil {
149
+ return 0 , fmt .Errorf ("invalid value for IntOrString: %v" , err )
150
+ }
151
+ if isPercent {
152
+ if roundUp {
153
+ value = int (math .Ceil (float64 (value ) * (float64 (total )) / 100 ))
154
+ } else {
155
+ value = int (math .Floor (float64 (value ) * (float64 (total )) / 100 ))
156
+ }
157
+ }
158
+ return value , nil
159
+ }
160
+
161
+ // GetValueFromIntOrPercent was deprecated in favor of
162
+ // GetScaledValueFromIntOrPercent. This method was treating all int as a numeric value and all
163
+ // strings with or without a percent symbol as a percentage value.
164
+ // Deprecated
138
165
func GetValueFromIntOrPercent (intOrPercent * IntOrString , total int , roundUp bool ) (int , error ) {
139
166
if intOrPercent == nil {
140
167
return 0 , errors .New ("nil value for IntOrString" )
@@ -153,6 +180,8 @@ func GetValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool
153
180
return value , nil
154
181
}
155
182
183
+ // getIntOrPercentValue is a legacy function and only meant to be called by GetValueFromIntOrPercent
184
+ // For a more correct implementation call getIntOrPercentSafely
156
185
func getIntOrPercentValue (intOrStr * IntOrString ) (int , bool , error ) {
157
186
switch intOrStr .Type {
158
187
case Int :
@@ -167,3 +196,25 @@ func getIntOrPercentValue(intOrStr *IntOrString) (int, bool, error) {
167
196
}
168
197
return 0 , false , fmt .Errorf ("invalid type: neither int nor percentage" )
169
198
}
199
+
200
+ func getIntOrPercentValueSafely (intOrStr * IntOrString ) (int , bool , error ) {
201
+ switch intOrStr .Type {
202
+ case Int :
203
+ return intOrStr .IntValue (), false , nil
204
+ case String :
205
+ isPercent := false
206
+ s := intOrStr .StrVal
207
+ if strings .HasSuffix (s , "%" ) {
208
+ isPercent = true
209
+ s = strings .TrimSuffix (intOrStr .StrVal , "%" )
210
+ } else {
211
+ return 0 , false , fmt .Errorf ("invalid type: string is not a percentage" )
212
+ }
213
+ v , err := strconv .Atoi (s )
214
+ if err != nil {
215
+ return 0 , false , fmt .Errorf ("invalid value %q: %v" , intOrStr .StrVal , err )
216
+ }
217
+ return int (v ), isPercent , nil
218
+ }
219
+ return 0 , false , fmt .Errorf ("invalid type: neither int nor percentage" )
220
+ }
0 commit comments