Update stdlib
[mirror/dsa-puppet.git] / 3rdparty / modules / stdlib / lib / puppet / parser / functions / validate_integer.rb
1 module Puppet::Parser::Functions
2
3   newfunction(:validate_integer, :doc => <<-'ENDHEREDOC') do |args|
4     Validate that the first argument is an integer (or an array of integers). 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 an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer.
13
14     The following values will pass:
15
16       validate_integer(1)
17       validate_integer(1, 2)
18       validate_integer(1, 1)
19       validate_integer(1, 2, 0)
20       validate_integer(2, 2, 2)
21       validate_integer(2, '', 0)
22       validate_integer(2, undef, 0)
23       $foo = undef
24       validate_integer(2, $foo, 0)
25       validate_integer([1,2,3,4,5], 6)
26       validate_integer([1,2,3,4,5], 6, 0)
27
28     Plus all of the above, but any combination of values passed as strings ('1' or "1").
29     Plus all of the above, but with (correct) combinations of negative integer values.
30
31     The following values will not:
32
33       validate_integer(true)
34       validate_integer(false)
35       validate_integer(7.0)
36       validate_integer({ 1 => 2 })
37       $foo = undef
38       validate_integer($foo)
39       validate_integer($foobaridontexist)
40
41       validate_integer(1, 0)
42       validate_integer(1, true)
43       validate_integer(1, '')
44       validate_integer(1, undef)
45       validate_integer(1, , 0)
46       validate_integer(1, 2, 3)
47       validate_integer(1, 3, 2)
48       validate_integer(1, 3, true)
49
50     Plus all of the above, but any combination of values passed as strings ('false' or "false").
51     Plus all of the above, but with incorrect combinations of negative integer values.
52     Plus all of the above, but with non-integer items in arrays or maximum / minimum argument.
53
54     ENDHEREDOC
55
56     function_deprecation([:validate_integer, 'This method is deprecated, please use the stdlib validate_legacy function, with Stdlib::Compat::Integer. There is further documentation for validate_legacy function in the README.'])
57
58     # tell the user we need at least one, and optionally up to two other parameters
59     raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4
60
61     input, max, min = *args
62
63     # check maximum parameter
64     if args.length > 1
65       max = max.to_s
66       # allow max to be empty (or undefined) if we have a minimum set
67       if args.length > 2 and max == ''
68         max = nil
69       else
70         begin
71           max = Integer(max)
72         rescue TypeError, ArgumentError
73           raise Puppet::ParseError, "validate_integer(): Expected second argument to be unset or an Integer, got #{max}:#{max.class}"
74         end
75       end
76     else
77       max = nil
78     end
79
80     # check minimum parameter
81     if args.length > 2
82       begin
83         min = Integer(min.to_s)
84       rescue TypeError, ArgumentError
85         raise Puppet::ParseError, "validate_integer(): Expected third argument to be unset or an Integer, got #{min}:#{min.class}"
86       end
87     else
88       min = nil
89     end
90
91     # ensure that min < max
92     if min and max and min > max
93       raise Puppet::ParseError, "validate_integer(): Expected second argument to be larger than third argument, got #{max} < #{min}"
94     end
95
96     # create lamba validator function
97     validator = lambda do |num|
98       # check input < max
99       if max and num > max
100         raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
101       end
102       # check input > min (this will only be checked if no exception has been raised before)
103       if min and num < min
104         raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
105       end
106     end
107
108     # if this is an array, handle it.
109     case input
110     when Array
111       # check every element of the array
112       input.each_with_index do |arg, pos|
113         begin
114           raise TypeError if arg.is_a?(Hash)
115           arg = Integer(arg.to_s)
116           validator.call(arg)
117         rescue TypeError, ArgumentError
118           raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}"
119         end
120       end
121     # for the sake of compatibility with ruby 1.8, we need extra handling of hashes
122     when Hash
123       raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
124     # check the input. this will also fail any stuff other than pure, shiny integers
125     else
126       begin
127         input = Integer(input.to_s)
128         validator.call(input)
129       rescue TypeError, ArgumentError
130         raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
131       end
132     end
133   end
134 end