windoo 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES.md +9 -0
- data/LICENSE.txt +177 -0
- data/README.md +222 -0
- data/lib/windoo/base_classes/array_manager.rb +335 -0
- data/lib/windoo/base_classes/criteria_manager.rb +327 -0
- data/lib/windoo/base_classes/criterion.rb +226 -0
- data/lib/windoo/base_classes/json_object.rb +472 -0
- data/lib/windoo/configuration.rb +221 -0
- data/lib/windoo/connection/actions.rb +152 -0
- data/lib/windoo/connection/attributes.rb +156 -0
- data/lib/windoo/connection/connect.rb +402 -0
- data/lib/windoo/connection/constants.rb +55 -0
- data/lib/windoo/connection/token.rb +489 -0
- data/lib/windoo/connection.rb +92 -0
- data/lib/windoo/converters.rb +31 -0
- data/lib/windoo/exceptions.rb +34 -0
- data/lib/windoo/mixins/api_collection.rb +408 -0
- data/lib/windoo/mixins/constants.rb +43 -0
- data/lib/windoo/mixins/default_connection.rb +75 -0
- data/lib/windoo/mixins/immutable.rb +34 -0
- data/lib/windoo/mixins/loading.rb +38 -0
- data/lib/windoo/mixins/patch/component.rb +102 -0
- data/lib/windoo/mixins/software_title/extension_attribute.rb +106 -0
- data/lib/windoo/mixins/utility.rb +23 -0
- data/lib/windoo/objects/capability.rb +82 -0
- data/lib/windoo/objects/capability_manager.rb +52 -0
- data/lib/windoo/objects/component.rb +99 -0
- data/lib/windoo/objects/component_criteria_manager.rb +26 -0
- data/lib/windoo/objects/component_criterion.rb +66 -0
- data/lib/windoo/objects/extension_attribute.rb +149 -0
- data/lib/windoo/objects/kill_app.rb +92 -0
- data/lib/windoo/objects/kill_app_manager.rb +89 -0
- data/lib/windoo/objects/patch.rb +235 -0
- data/lib/windoo/objects/patch_manager.rb +240 -0
- data/lib/windoo/objects/requirement.rb +85 -0
- data/lib/windoo/objects/requirement_manager.rb +52 -0
- data/lib/windoo/objects/software_title.rb +407 -0
- data/lib/windoo/validate.rb +548 -0
- data/lib/windoo/version.rb +15 -0
- data/lib/windoo/zeitwerk_config.rb +158 -0
- data/lib/windoo.rb +56 -0
- metadata +141 -0
@@ -0,0 +1,548 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
#
|
6
|
+
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
module Windoo
|
10
|
+
|
11
|
+
# A collection of methods implementing data constraints
|
12
|
+
#
|
13
|
+
# Some of these methods can take multiple input types, such as a String
|
14
|
+
# or an number. All of them will either raise an exception
|
15
|
+
# if the value isn't valid, or will return a standardized form of the input
|
16
|
+
# (e.g. a number or a Time, even if given a String)
|
17
|
+
#
|
18
|
+
module Validate
|
19
|
+
|
20
|
+
# Thes methods all raise this error
|
21
|
+
def self.raise_invalid_data_error(msg)
|
22
|
+
raise Windoo::InvalidDataError, msg
|
23
|
+
end
|
24
|
+
|
25
|
+
# Validate that a value is valid based on its
|
26
|
+
# definition in an objects OAPI_PROPERTIES constant.
|
27
|
+
#
|
28
|
+
# @param val [Object] The value to validate
|
29
|
+
#
|
30
|
+
# @param klass [Class, Symbol] The class which the val must be
|
31
|
+
#
|
32
|
+
# @param msg[String] A custom error message when the value is invalid
|
33
|
+
#
|
34
|
+
# @return [Boolean] the valid boolean
|
35
|
+
#
|
36
|
+
def self.json_attr(val, attr_def:, attr_name: nil)
|
37
|
+
# check that the new val is not nil if its required
|
38
|
+
val = not_nil(val, attr_name: attr_name) if attr_def[:required]
|
39
|
+
|
40
|
+
# if the new val is nil here, then nil is OK andd we shouldn't
|
41
|
+
# check anything else
|
42
|
+
return val if val.nil?
|
43
|
+
|
44
|
+
val =
|
45
|
+
case attr_def[:class]
|
46
|
+
when :Boolean
|
47
|
+
boolean val, attr_name: attr_name
|
48
|
+
|
49
|
+
when :String
|
50
|
+
fully_validate_string(val, attr_def: attr_def, attr_name: attr_name)
|
51
|
+
|
52
|
+
when :Integer
|
53
|
+
fully_validate_integer(val, attr_def: attr_def, attr_name: attr_name)
|
54
|
+
|
55
|
+
when :Number
|
56
|
+
fully_validate_number(val, attr_def: attr_def, attr_name: attr_name)
|
57
|
+
|
58
|
+
when :Hash
|
59
|
+
hash val, attr_name: attr_name
|
60
|
+
|
61
|
+
when :Symbol
|
62
|
+
symbol val, attr_name: attr_name
|
63
|
+
|
64
|
+
when :Time
|
65
|
+
time val, attr_name: attr_name
|
66
|
+
|
67
|
+
else
|
68
|
+
val
|
69
|
+
end # case
|
70
|
+
|
71
|
+
# Now that the val is in whatever correct format after the above tests,
|
72
|
+
# we test for enum membership if needed
|
73
|
+
# otherwise, just return the val
|
74
|
+
if attr_def[:enum]
|
75
|
+
in_enum val, enum: attr_def[:enum], attr_name: attr_name
|
76
|
+
else
|
77
|
+
val
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# run all the possible validations on a string
|
82
|
+
def self.fully_validate_string(val, attr_def:, attr_name: nil)
|
83
|
+
val = string val, attr_name: attr_name
|
84
|
+
|
85
|
+
min_length val, min: attr_def[:min_length], attr_name: attr_name if attr_def[:min_length]
|
86
|
+
max_length val, max: attr_def[:max_length], attr_name: attr_name if attr_def[:max_length]
|
87
|
+
matches_pattern val, attr_def[:pattern], attr_name: attr_name if attr_def[:pattern]
|
88
|
+
|
89
|
+
val
|
90
|
+
end
|
91
|
+
|
92
|
+
# run all the possible validations on an integer
|
93
|
+
def self.fully_validate_integer(val, attr_def:, attr_name: nil)
|
94
|
+
val = integer val, attr_name: attr_name
|
95
|
+
validate_numeric_constraints(val, attr_def: attr_def, attr_name: attr_name)
|
96
|
+
end
|
97
|
+
|
98
|
+
# run all the possible validations on a 'number'
|
99
|
+
def self.fully_validate_number(val, attr_def:, attr_name: nil)
|
100
|
+
val =
|
101
|
+
if %w[float double].include? attr_def[:format]
|
102
|
+
float val, attr_name: attr_name
|
103
|
+
else
|
104
|
+
number val, attr_name: attr_name
|
105
|
+
end
|
106
|
+
validate_numeric_constraints(val, attr_def: attr_def, attr_name: attr_name)
|
107
|
+
end
|
108
|
+
|
109
|
+
# run the numeric constraint validations for any numeric value
|
110
|
+
# The number itself must already be validated
|
111
|
+
def self.validate_numeric_constraints(val, attr_def:, attr_name: nil)
|
112
|
+
ex_min = attr_def[:exclusive_minimum]
|
113
|
+
ex_max = attr_def[:exclusive_maximum]
|
114
|
+
mult_of = attr_def[:multiple_of]
|
115
|
+
|
116
|
+
minimum val, min: attr_def[:minimum], exclusive: ex_min, attr_name: attr_name if attr_def[:minimum]
|
117
|
+
maximum val, max: attr_def[:maximum], exclusive: ex_max, attr_name: attr_name if attr_def[:maximum]
|
118
|
+
multiple_of val, multiplier: mult_of, attr_name: attr_name if mult_of
|
119
|
+
|
120
|
+
val
|
121
|
+
end
|
122
|
+
|
123
|
+
# run the array constraint validations for an array value.
|
124
|
+
# The individual array items must already be validated
|
125
|
+
def self.array_constraints(val, attr_def:, attr_name: nil)
|
126
|
+
min_items val, min: attr_def[:minItems], attr_name: attr_name if attr_def[:minItems]
|
127
|
+
max_items val, max: attr_def[:maxItems], attr_name: attr_name if attr_def[:maxItems]
|
128
|
+
unique_array val, attr_name: attr_name if attr_def[:uniqueItems]
|
129
|
+
|
130
|
+
val
|
131
|
+
end
|
132
|
+
|
133
|
+
# validate that a value is of a specific class
|
134
|
+
#
|
135
|
+
# @param val [Object] The value to validate
|
136
|
+
#
|
137
|
+
# @param klass [Class, Symbol] The class which the val must be an instance of
|
138
|
+
#
|
139
|
+
# @param msg[String] A custom error message when the value is invalid
|
140
|
+
#
|
141
|
+
# @return [Object] the valid value
|
142
|
+
#
|
143
|
+
def self.class_instance(val, klass:, attr_name: nil, msg: nil)
|
144
|
+
return val if val.instance_of? klass
|
145
|
+
|
146
|
+
# try to instantiate the class with the value. It should raise an error
|
147
|
+
# if not good
|
148
|
+
klass.new val
|
149
|
+
rescue StandardError => e
|
150
|
+
unless msg
|
151
|
+
msg = +"#{attr_name} value must be a #{klass}, or #{klass}.new must accept it as the only parameter,"
|
152
|
+
msg << "but #{klass}.new raised: #{e.class}: #{e}"
|
153
|
+
end
|
154
|
+
raise_invalid_data_error(msg)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Confirm that the given value is a boolean value, accepting
|
158
|
+
# strings and symbols and returning real booleans as needed
|
159
|
+
# Accepts: true, false, 'true', 'false', 'yes', 'no', 't','f', 'y', or 'n'
|
160
|
+
# as strings or symbols, case insensitive
|
161
|
+
#
|
162
|
+
# TODO: use this throughout ruby-jss
|
163
|
+
#
|
164
|
+
# @param val [Boolean,String,Symbol] The value to validate
|
165
|
+
#
|
166
|
+
# @param msg[String] A custom error message when the value is invalid
|
167
|
+
#
|
168
|
+
# @return [Boolean] the valid boolean
|
169
|
+
#
|
170
|
+
def self.boolean(val, attr_name: nil, msg: nil)
|
171
|
+
return val if Windoo::TRUE_FALSE.include? val
|
172
|
+
return true if val.to_s =~ /^(t(rue)?|y(es)?)$/i
|
173
|
+
return false if val.to_s =~ /^(f(alse)?|no?)$/i
|
174
|
+
|
175
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be boolean true or false, or an equivalent string or symbol")
|
176
|
+
end
|
177
|
+
|
178
|
+
# Confirm that a value is an number or a string representation of an
|
179
|
+
# number. Return the number, or raise an error
|
180
|
+
#
|
181
|
+
# @param val[Object] the value to validate
|
182
|
+
#
|
183
|
+
# @param msg[String] A custom error message when the value is invalid
|
184
|
+
#
|
185
|
+
# @return [Integer]
|
186
|
+
#
|
187
|
+
def self.number(val, attr_name: nil, msg: nil)
|
188
|
+
if val.ia_a?(Integer) || val.is_a?(Float)
|
189
|
+
return val
|
190
|
+
|
191
|
+
elsif val.is_a?(String)
|
192
|
+
|
193
|
+
if val.j_integer?
|
194
|
+
return val.to_i
|
195
|
+
elsif val.j_float?
|
196
|
+
return val.to_f
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be a number")
|
202
|
+
end
|
203
|
+
|
204
|
+
# Confirm that a value is an integer or a string representation of an
|
205
|
+
# integer. Return the integer, or raise an error
|
206
|
+
#
|
207
|
+
# @param val[Object] the value to validate
|
208
|
+
#
|
209
|
+
# @param msg[String] A custom error message when the value is invalid
|
210
|
+
#
|
211
|
+
# @return [Integer]
|
212
|
+
#
|
213
|
+
def self.integer(val, attr_name: nil, msg: nil)
|
214
|
+
val = val.to_i if val.is_a?(String) && val.j_integer?
|
215
|
+
return val if val.is_a? Integer
|
216
|
+
|
217
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be an integer")
|
218
|
+
end
|
219
|
+
|
220
|
+
# Confirm that a value is a Float or a string representation of a Float
|
221
|
+
# Return the Float, or raise an error
|
222
|
+
#
|
223
|
+
# @param val[Object] the value to validate
|
224
|
+
#
|
225
|
+
# @param msg[String] A custom error message when the value is invalid
|
226
|
+
#
|
227
|
+
# @return [Float]
|
228
|
+
#
|
229
|
+
def self.float(val, attr_name: nil, msg: nil)
|
230
|
+
val = val.to_f if val.is_a?(Integer)
|
231
|
+
val = val.to_f if val.is_a?(String) && (val.j_float? || val.j_integer?)
|
232
|
+
return val if val.is_a? Float
|
233
|
+
|
234
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be an floating point number")
|
235
|
+
end
|
236
|
+
|
237
|
+
# Confirm that a value is a Hash
|
238
|
+
# Return the Hash, or raise an error
|
239
|
+
#
|
240
|
+
# @param val[Object] the value to validate
|
241
|
+
#
|
242
|
+
# @param msg[String] A custom error message when the value is invalid
|
243
|
+
#
|
244
|
+
# @return [Hash]
|
245
|
+
#
|
246
|
+
def self.object(val, attr_name: nil, msg: nil)
|
247
|
+
return val if val.is_a? Hash
|
248
|
+
|
249
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be a Hash")
|
250
|
+
end
|
251
|
+
|
252
|
+
# Confirm that a value is a Symbol, or can be coerced into one
|
253
|
+
# Return the Symbol, or raise an error
|
254
|
+
#
|
255
|
+
# @param val [#to_sym] the value to validate
|
256
|
+
#
|
257
|
+
# @param msg [String] A custom error message when the value is invalid
|
258
|
+
#
|
259
|
+
# @return [Symbol]
|
260
|
+
#
|
261
|
+
def self.symbol(val, attr_name: nil, msg: nil)
|
262
|
+
return val.to_sym if val.respond_to? :to_sym
|
263
|
+
|
264
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be a Symbol")
|
265
|
+
end
|
266
|
+
|
267
|
+
# Confirm that a value is a Time, or can be parsed into
|
268
|
+
#
|
269
|
+
# Return the ISO8601 formatted String, or raise an error
|
270
|
+
#
|
271
|
+
# @param val [Time, #to_s] the value to validate
|
272
|
+
#
|
273
|
+
# @param msg [String] A custom error message when the value is invalid
|
274
|
+
#
|
275
|
+
# @return [Time] The Time
|
276
|
+
#
|
277
|
+
def self.time(val, attr_name: nil, msg: nil)
|
278
|
+
val.is_a?(Time) ? val : Time.parse(val.to_s)
|
279
|
+
rescue StandardError
|
280
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be a Time, or a String to be used with Time.parse")
|
281
|
+
end
|
282
|
+
|
283
|
+
# Confirm that a value is a String
|
284
|
+
# Return the String, or raise an error
|
285
|
+
#
|
286
|
+
# @param val[Object] the value to validate
|
287
|
+
#
|
288
|
+
# @param msg[String] A custom error message when the value is invalid
|
289
|
+
#
|
290
|
+
# @param to_s: [Boolean] If true, this method always succeds and returns
|
291
|
+
# the result of calling #to_s on the value
|
292
|
+
#
|
293
|
+
# @return [Hash]
|
294
|
+
#
|
295
|
+
def self.string(val, attr_name: nil, msg: nil, to_s: false)
|
296
|
+
val = val.to_s if to_s
|
297
|
+
return val if val.is_a? String
|
298
|
+
|
299
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be a String")
|
300
|
+
end
|
301
|
+
|
302
|
+
# validate that the given value is greater than or equal to some minimum
|
303
|
+
#
|
304
|
+
# If exclusive, the min value is excluded from the range and
|
305
|
+
# the value must be greater than the min.
|
306
|
+
#
|
307
|
+
# While intended for Numbers, this will work for any Comparable objects
|
308
|
+
#
|
309
|
+
# @param val [Object] the thing to validate
|
310
|
+
#
|
311
|
+
# @param min [Object] A value that the val must be greater than or equal to
|
312
|
+
#
|
313
|
+
# @param exclusuve [Boolean] Should the min be excluded from the valid range?
|
314
|
+
# true: val must be > min, false: val must be >= min
|
315
|
+
#
|
316
|
+
# @param msg [String] A custom error message when the value is invalid
|
317
|
+
#
|
318
|
+
# @return [String] the valid value
|
319
|
+
#
|
320
|
+
def self.minimum(val, min:, attr_name: nil, exclusive: false, msg: nil)
|
321
|
+
if exclusive
|
322
|
+
return val if val > min
|
323
|
+
elsif val >= min
|
324
|
+
return val
|
325
|
+
end
|
326
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be >= #{min}")
|
327
|
+
end
|
328
|
+
|
329
|
+
# validate that the given value is less than or equal to some maximum
|
330
|
+
#
|
331
|
+
# While intended for Numbers, this will work for any Comparable objects
|
332
|
+
#
|
333
|
+
# If exclusive, the max value is excluded from the range and
|
334
|
+
# the value must be less than the max.
|
335
|
+
#
|
336
|
+
# @param val [Object] the thing to validate
|
337
|
+
#
|
338
|
+
# @param max[Object] A value that the val must be less than or equal to
|
339
|
+
#
|
340
|
+
# @param exclusuve [Boolean] Should the max be excluded from the valid range?
|
341
|
+
# true: val must be < max, false: val must be <= max
|
342
|
+
#
|
343
|
+
# @param msg[String] A custom error message when the value is invalid
|
344
|
+
#
|
345
|
+
# @return [String] the valid value
|
346
|
+
#
|
347
|
+
def self.maximum(val, max:, attr_name: nil, exclusive: false, msg: nil)
|
348
|
+
if exclusive
|
349
|
+
return val if val < max
|
350
|
+
elsif val <= max
|
351
|
+
return val
|
352
|
+
end
|
353
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be <= #{max}")
|
354
|
+
end
|
355
|
+
|
356
|
+
# Validate that a given number is multiple of some other given number
|
357
|
+
#
|
358
|
+
# @param val [Number] the number to validate
|
359
|
+
#
|
360
|
+
# @param multiplier [Number] the number what the val must be a multiple of.
|
361
|
+
# this must be positive.
|
362
|
+
#
|
363
|
+
# @param msg[String] A custom error message when the value is invalid
|
364
|
+
#
|
365
|
+
# @return [String] the valid value
|
366
|
+
#
|
367
|
+
def self.multiple_of(val, multiplier:, attr_name: nil, msg: nil)
|
368
|
+
unless multiplier.is_a?(Numeric) && multiplier.positive?
|
369
|
+
raise ArgumentError,
|
370
|
+
'multiplier must be a positive number'
|
371
|
+
end
|
372
|
+
raise Windoo::InvalidDataError, 'Value must be a number' unless val.is_a?(Numeric)
|
373
|
+
|
374
|
+
return val if (val % multiplier).zero?
|
375
|
+
|
376
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be a multiple of #{multiplier}")
|
377
|
+
end
|
378
|
+
|
379
|
+
# validate that the given value's length is greater than or equal to some minimum
|
380
|
+
#
|
381
|
+
# While this is intended for Strings, it will work for any object that responds
|
382
|
+
# to #length
|
383
|
+
#
|
384
|
+
# @param val [Object] the value to validate
|
385
|
+
#
|
386
|
+
# @param min [Object] The minimum length allowed
|
387
|
+
#
|
388
|
+
# @param msg [String] A custom error message when the value is invalid
|
389
|
+
#
|
390
|
+
# @return [String] the valid value
|
391
|
+
#
|
392
|
+
def self.min_length(val, min:, attr_name: nil, msg: nil)
|
393
|
+
raise ArgumentError, 'min must be a number' unless min.is_a?(Numeric)
|
394
|
+
return val if val.length >= min
|
395
|
+
|
396
|
+
raise_invalid_data_error(msg || "length of #{attr_name} value must be >= #{min}")
|
397
|
+
end
|
398
|
+
|
399
|
+
# validate that the given value's length is less than or equal to some maximum
|
400
|
+
#
|
401
|
+
# While this is intended for Strings, it will work for any object that responds
|
402
|
+
# to #length
|
403
|
+
#
|
404
|
+
# @param val [Object] the value to validate
|
405
|
+
#
|
406
|
+
# @param max [Object] the maximum length allowed
|
407
|
+
#
|
408
|
+
# @param msg [String] A custom error message when the value is invalid
|
409
|
+
#
|
410
|
+
# @return [String] the valid value
|
411
|
+
#
|
412
|
+
def self.max_length(val, max:, attr_name: nil, msg: nil)
|
413
|
+
raise ArgumentError, 'max must be a number' unless max.is_a?(Numeric)
|
414
|
+
return val if val.length <= max
|
415
|
+
|
416
|
+
raise_invalid_data_error(msg || "length of #{attr_name} value must be <= #{max}")
|
417
|
+
end
|
418
|
+
|
419
|
+
# validate that the given value contains at least some minimum number of items
|
420
|
+
#
|
421
|
+
# While this is intended for Arrays, it will work for any object that responds
|
422
|
+
# to #size
|
423
|
+
#
|
424
|
+
# @param val [Object] the value to validate
|
425
|
+
#
|
426
|
+
# @param min [Object] the minimum number of items allowed
|
427
|
+
#
|
428
|
+
# @param msg [String] A custom error message when the value is invalid
|
429
|
+
#
|
430
|
+
# @return [String] the valid value
|
431
|
+
#
|
432
|
+
def self.min_items(val, min:, attr_name: nil, msg: nil)
|
433
|
+
raise ArgumentError, 'min must be a number' unless min.is_a?(Numeric)
|
434
|
+
return val if val.size >= min
|
435
|
+
|
436
|
+
raise_invalid_data_error(msg || "#{attr_name} value must contain at least #{min} items")
|
437
|
+
end
|
438
|
+
|
439
|
+
# validate that the given value contains no more than some maximum number of items
|
440
|
+
#
|
441
|
+
# While this is intended for Arrays, it will work for any object that responds
|
442
|
+
# to #size
|
443
|
+
#
|
444
|
+
# @param val [Object] the value to validate
|
445
|
+
#
|
446
|
+
# @param max [Object] the maximum number of items allowed
|
447
|
+
#
|
448
|
+
# @param msg [String] A custom error message when the value is invalid
|
449
|
+
#
|
450
|
+
# @return [String] the valid value
|
451
|
+
#
|
452
|
+
def self.max_items(val, max:, attr_name: nil, msg: nil)
|
453
|
+
raise ArgumentError, 'max must be a number' unless max.is_a?(Numeric)
|
454
|
+
return val if val.size <= max
|
455
|
+
|
456
|
+
raise_invalid_data_error(msg || "#{attr_name} value must contain no more than #{max} items")
|
457
|
+
end
|
458
|
+
|
459
|
+
# validate that an array has only unique items, no duplicate values
|
460
|
+
#
|
461
|
+
# @param val [Array] The array to validate
|
462
|
+
#
|
463
|
+
# @param msg [String] A custom error message when the value is invalid
|
464
|
+
#
|
465
|
+
# @param return [Array] the valid array
|
466
|
+
#
|
467
|
+
def self.unique_array(val, attr_name: nil, msg: nil)
|
468
|
+
raise ArgumentError, 'Value must be an Array' unless val.is_a?(Array)
|
469
|
+
return val if val.uniq.size == val.size
|
470
|
+
|
471
|
+
raise_invalid_data_error(msg || "#{attr_name} value must contain only unique items")
|
472
|
+
end
|
473
|
+
|
474
|
+
# validate that a value is not nil
|
475
|
+
#
|
476
|
+
# @param val[Object] the value to validate
|
477
|
+
#
|
478
|
+
# @param msg[String] A custom error message when the value is invalid
|
479
|
+
#
|
480
|
+
# @return [Object] the valid value
|
481
|
+
#
|
482
|
+
def self.not_nil(val, attr_name: nil, msg: nil)
|
483
|
+
return val unless val.nil?
|
484
|
+
|
485
|
+
raise_invalid_data_error(msg || "#{attr_name} value may not be nil")
|
486
|
+
end
|
487
|
+
|
488
|
+
# Does a value exist in a given enum array?
|
489
|
+
#
|
490
|
+
# @param val [Object] The thing that must be in the enum
|
491
|
+
#
|
492
|
+
# @param enum [Array] the enum of allowed values
|
493
|
+
#
|
494
|
+
# @param msg[String] A custom error message when the value is invalid
|
495
|
+
#
|
496
|
+
# @return [Object] The valid object
|
497
|
+
#
|
498
|
+
def self.in_enum(val, enum:, attr_name: nil, msg: nil)
|
499
|
+
return val if enum.include? val
|
500
|
+
|
501
|
+
raise_invalid_data_error(msg || "#{attr_name} value must be one of: #{enum.join ', '}")
|
502
|
+
end
|
503
|
+
|
504
|
+
# Does a string match a given regular expression?
|
505
|
+
#
|
506
|
+
# @param val [String] The value to match
|
507
|
+
#
|
508
|
+
# @param pattern [pattern] the regular expression
|
509
|
+
#
|
510
|
+
# @param msg[String] A custom error message when the value is invalid
|
511
|
+
#
|
512
|
+
# @return [Object] The valid object
|
513
|
+
#
|
514
|
+
def self.matches_pattern(val, pattern:, attr_name: nil, msg: nil)
|
515
|
+
return val if val =~ pattern
|
516
|
+
|
517
|
+
raise_invalid_data_error(msg || "#{attr_name} value does not match RegExp: #{pattern}")
|
518
|
+
end
|
519
|
+
|
520
|
+
# confirm we were given a valid container when creating
|
521
|
+
#
|
522
|
+
# @param new_object_class [Class] the class of the new object we are creating
|
523
|
+
#
|
524
|
+
# @param container [Object] The object that will contain tne new object
|
525
|
+
# we are creating
|
526
|
+
#
|
527
|
+
# @return [Object, nil] The valid container for the new object
|
528
|
+
#
|
529
|
+
def self.container_for_new_object(new_object_class:, container: nil)
|
530
|
+
# software titles don't have containers.
|
531
|
+
return if new_object_class == Windoo::SoftwareTitle
|
532
|
+
|
533
|
+
unless container
|
534
|
+
raise Windoo::UnsupportedError,
|
535
|
+
'All new objects other than SoftwareTitle must pass in a container: object'
|
536
|
+
end
|
537
|
+
|
538
|
+
unless new_object_class::CONTAINER_CLASS == container.class
|
539
|
+
raise Windoo::InvalidDataError,
|
540
|
+
"The container for new #{new_object_class} objects must be a #{new_object_class::CONTAINER_CLASS} object"
|
541
|
+
end
|
542
|
+
|
543
|
+
container
|
544
|
+
end
|
545
|
+
|
546
|
+
end # module validate
|
547
|
+
|
548
|
+
end # module Windoo
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright 2025 Pixar
|
2
|
+
#
|
3
|
+
# Licensed under the terms set forth in the LICENSE.txt file available at
|
4
|
+
# at the root of this project.
|
5
|
+
#
|
6
|
+
#
|
7
|
+
|
8
|
+
# frozen_string_literal: true
|
9
|
+
|
10
|
+
# main module
|
11
|
+
module Windoo
|
12
|
+
|
13
|
+
VERSION = '1.0.1'
|
14
|
+
|
15
|
+
end # module
|