Module: AnyVali::Format::Validators

Defined in:
lib/anyvali/format/validators.rb

Constant Summary collapse

EMAIL_REGEX =
/\A[^@\s]+@[^@\s]+\.[^@\s]+\z/
UUID_REGEX =
/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
IPV4_REGEX =

Strict IPv4: no leading zeros, octets 0-255

/\A(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\z/
DATETIME_REGEX =
/\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})\z/
DATE_REGEX =
/\A\d{4}-\d{2}-\d{2}\z/

Class Method Summary collapse

Class Method Details

.valid_date?(value) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
# File 'lib/anyvali/format/validators.rb', line 73

def valid_date?(value)
  return false unless DATE_REGEX.match?(value)
  Date.parse(value)
  true
rescue Date::Error, ArgumentError
  false
end

.valid_datetime?(value) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
# File 'lib/anyvali/format/validators.rb', line 81

def valid_datetime?(value)
  return false unless DATETIME_REGEX.match?(value)
  # Validate the date part
  date_part = value[0..9]
  valid_date?(date_part)
end

.valid_email?(value) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/anyvali/format/validators.rb', line 41

def valid_email?(value)
  EMAIL_REGEX.match?(value)
end

.valid_ipv4?(value) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
59
60
61
62
# File 'lib/anyvali/format/validators.rb', line 56

def valid_ipv4?(value)
  # Must match strict pattern (no leading zeros)
  return false unless IPV4_REGEX.match?(value)
  # Check for leading zeros explicitly
  parts = value.split(".")
  parts.length == 4 && parts.all? { |p| p == "0" || !p.start_with?("0") }
end

.valid_ipv6?(value) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
67
68
69
70
71
# File 'lib/anyvali/format/validators.rb', line 64

def valid_ipv6?(value)
  addr = IPAddr.new(value)
  addr.ipv6?
rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
  false
rescue ArgumentError
  false
end

.valid_url?(value) ⇒ Boolean

Returns:

  • (Boolean)


45
46
47
48
49
50
# File 'lib/anyvali/format/validators.rb', line 45

def valid_url?(value)
  uri = URI.parse(value)
  %w[http https].include?(uri.scheme) && !uri.host.nil?
rescue URI::InvalidURIError
  false
end

.valid_uuid?(value) ⇒ Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/anyvali/format/validators.rb', line 52

def valid_uuid?(value)
  UUID_REGEX.match?(value)
end

.validate(value, format, path, issues) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/anyvali/format/validators.rb', line 19

def validate(value, format, path, issues)
  valid = case format
          when "email" then valid_email?(value)
          when "url" then valid_url?(value)
          when "uuid" then valid_uuid?(value)
          when "ipv4" then valid_ipv4?(value)
          when "ipv6" then valid_ipv6?(value)
          when "date" then valid_date?(value)
          when "date-time" then valid_datetime?(value)
          else false
          end

  unless valid
    issues << ValidationIssue.new(
      code: IssueCodes::INVALID_STRING,
      path: path,
      expected: format,
      received: value
    )
  end
end