Update stdlib
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / validate_numeric.rb
1 module Puppet::Parser::Functions
2
3   newfunction(:validate_numeric, :doc => <<-'ENDHEREDOC') do |args|
4     Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail.
5
6     The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
7
8     The third argument is optional and passes a minimum.  (All elements of) the first argument has to be greater or equal to this min.
9     If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
10     if (all elements of) the first argument are greater or equal to the given minimum.
11
12     It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric.
13
14     For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too.
15
16     ENDHEREDOC
17
18     function_deprecation([:validate_numeric, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Numeric. There is further documentation for validate_legacy function in the README.'])
19
20     # tell the user we need at least one, and optionally up to two other parameters
21     raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4
22
23     input, max, min = *args
24
25     # check maximum parameter
26     if args.length > 1
27       max = max.to_s
28       # allow max to be empty (or undefined) if we have a minimum set
29       if args.length > 2 and max == ''
30         max = nil
31       else
32         begin
33           max = Float(max)
34         rescue TypeError, ArgumentError
35           raise Puppet::ParseError, "validate_numeric(): Expected second argument to be unset or a Numeric, got #{max}:#{max.class}"
36         end
37       end
38     else
39       max = nil
40     end
41
42     # check minimum parameter
43     if args.length > 2
44       begin
45         min = Float(min.to_s)
46       rescue TypeError, ArgumentError
47         raise Puppet::ParseError, "validate_numeric(): Expected third argument to be unset or a Numeric, got #{min}:#{min.class}"
48       end
49     else
50       min = nil
51     end
52
53     # ensure that min < max
54     if min and max and min > max
55       raise Puppet::ParseError, "validate_numeric(): Expected second argument to be larger than third argument, got #{max} < #{min}"
56     end
57
58     # create lamba validator function
59     validator = lambda do |num|
60       # check input < max
61       if max and num > max
62         raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
63       end
64       # check input > min (this will only be checked if no exception has been raised before)
65       if min and num < min
66         raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
67       end
68     end
69
70     # if this is an array, handle it.
71     case input
72     when Array
73       # check every element of the array
74       input.each_with_index do |arg, pos|
75         begin
76           raise TypeError if arg.is_a?(Hash)
77           arg = Float(arg.to_s)
78           validator.call(arg)
79         rescue TypeError, ArgumentError
80           raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}"
81         end
82       end
83     # for the sake of compatibility with ruby 1.8, we need extra handling of hashes
84     when Hash
85       raise Puppet::ParseError, "validate_integer(): Expected first argument to be a Numeric or Array, got #{input.class}"
86     # check the input. this will also fail any stuff other than pure, shiny integers
87     else
88       begin
89         input = Float(input.to_s)
90         validator.call(input)
91       rescue TypeError, ArgumentError
92         raise Puppet::ParseError, "validate_numeric(): Expected first argument to be a Numeric or Array, got #{input.class}"
93       end
94     end
95   end
96 end