Module: EasyTalk::JsonSchemaEquality
- Defined in:
- lib/easy_talk/json_schema_equality.rb
Overview
Implements JSON Schema equality semantics for comparing values.
Per JSON Schema specification:
- Objects with same keys/values in different order are equal
- Numbers that are mathematically equal are equal (1 == 1.0)
- Type matters for non-numbers (true != 1, false != 0)
Constant Summary collapse
- MAX_DEPTH =
Maximum nesting depth to prevent SystemStackError on deeply nested structures
100
Class Method Summary collapse
-
.duplicates?(array) ⇒ Boolean
Check if an array contains duplicate values using JSON Schema equality.
-
.normalize(value, depth = 0) ⇒ Object
Normalize a value for JSON Schema equality comparison.
Class Method Details
.duplicates?(array) ⇒ Boolean
Check if an array contains duplicate values using JSON Schema equality. Uses a Set for O(n) performance and early termination on first duplicate.
17 18 19 20 |
# File 'lib/easy_talk/json_schema_equality.rb', line 17 def duplicates?(array) seen = Set.new array.any? { |item| !seen.add?(normalize(item)) } end |
.normalize(value, depth = 0) ⇒ Object
Normalize a value for JSON Schema equality comparison
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/easy_talk/json_schema_equality.rb', line 26 def normalize(value, depth = 0) raise ArgumentError, "Nesting depth exceeds maximum of #{MAX_DEPTH}" if depth > MAX_DEPTH case value when Hash # Convert keys to strings before sorting to handle mixed key types (Symbol/String) # and ensure consistent, order-independent comparison (JSON only has string keys) value.map { |k, v| [k.to_s, normalize(v, depth + 1)] }.sort when Array value.map { |item| normalize(item, depth + 1) } when Integer, Float # Normalize numbers to a canonical form for mathematical equality value.to_r else # Booleans, strings, nil - preserve as-is (type matters) value end end |