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