@@ -151,6 +151,33 @@ func ValueOrDefault(intOrPercent *IntOrString, defaultValue IntOrString) *IntOrS
151
151
return intOrPercent
152
152
}
153
153
154
+ // GetScaledValueFromIntOrPercent is meant to replace GetValueFromIntOrPercent.
155
+ // This method returns a scaled value from an IntOrString type. If the IntOrString
156
+ // is a percentage string value it's treated as a percentage and scaled appropriately
157
+ // in accordance to the total, if it's an int value it's treated as a a simple value and
158
+ // if it is a string value which is either non-numeric or numeric but lacking a trailing '%' it returns an error.
159
+ func GetScaledValueFromIntOrPercent (intOrPercent * IntOrString , total int , roundUp bool ) (int , error ) {
160
+ if intOrPercent == nil {
161
+ return 0 , errors .New ("nil value for IntOrString" )
162
+ }
163
+ value , isPercent , err := getIntOrPercentValueSafely (intOrPercent )
164
+ if err != nil {
165
+ return 0 , fmt .Errorf ("invalid value for IntOrString: %v" , err )
166
+ }
167
+ if isPercent {
168
+ if roundUp {
169
+ value = int (math .Ceil (float64 (value ) * (float64 (total )) / 100 ))
170
+ } else {
171
+ value = int (math .Floor (float64 (value ) * (float64 (total )) / 100 ))
172
+ }
173
+ }
174
+ return value , nil
175
+ }
176
+
177
+ // GetValueFromIntOrPercent was deprecated in favor of
178
+ // GetScaledValueFromIntOrPercent. This method was treating all int as a numeric value and all
179
+ // strings with or without a percent symbol as a percentage value.
180
+ // Deprecated
154
181
func GetValueFromIntOrPercent (intOrPercent * IntOrString , total int , roundUp bool ) (int , error ) {
155
182
if intOrPercent == nil {
156
183
return 0 , errors .New ("nil value for IntOrString" )
@@ -169,6 +196,8 @@ func GetValueFromIntOrPercent(intOrPercent *IntOrString, total int, roundUp bool
169
196
return value , nil
170
197
}
171
198
199
+ // getIntOrPercentValue is a legacy function and only meant to be called by GetValueFromIntOrPercent
200
+ // For a more correct implementation call getIntOrPercentSafely
172
201
func getIntOrPercentValue (intOrStr * IntOrString ) (int , bool , error ) {
173
202
switch intOrStr .Type {
174
203
case Int :
@@ -183,3 +212,25 @@ func getIntOrPercentValue(intOrStr *IntOrString) (int, bool, error) {
183
212
}
184
213
return 0 , false , fmt .Errorf ("invalid type: neither int nor percentage" )
185
214
}
215
+
216
+ func getIntOrPercentValueSafely (intOrStr * IntOrString ) (int , bool , error ) {
217
+ switch intOrStr .Type {
218
+ case Int :
219
+ return intOrStr .IntValue (), false , nil
220
+ case String :
221
+ isPercent := false
222
+ s := intOrStr .StrVal
223
+ if strings .HasSuffix (s , "%" ) {
224
+ isPercent = true
225
+ s = strings .TrimSuffix (intOrStr .StrVal , "%" )
226
+ } else {
227
+ return 0 , false , fmt .Errorf ("invalid type: string is not a percentage" )
228
+ }
229
+ v , err := strconv .Atoi (s )
230
+ if err != nil {
231
+ return 0 , false , fmt .Errorf ("invalid value %q: %v" , intOrStr .StrVal , err )
232
+ }
233
+ return int (v ), isPercent , nil
234
+ }
235
+ return 0 , false , fmt .Errorf ("invalid type: neither int nor percentage" )
236
+ }
0 commit comments