Class: GrapeOAS::RangeUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/grape_oas/range_utils.rb

Overview

Converts Range values into OpenAPI-compatible representations.

Constant Summary collapse

NUMERIC_TYPES =
[Constants::SchemaTypes::INTEGER, Constants::SchemaTypes::NUMBER].freeze

Class Method Summary collapse

Class Method Details

.apply_numeric_range(target, range) ⇒ Object

Writes numeric range constraints directly to any object with minimum=/maximum=/exclusive_maximum= setters (Schema, ConstraintSet, etc). Skips descending and infinite bounds.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/grape_oas/range_utils.rb', line 29

def apply_numeric_range(target, range)
  return unless range

  first_val = range.begin
  last_val = range.end

  return if descending?(first_val, last_val)

  target.minimum = first_val if finite_numeric?(first_val) && target.respond_to?(:minimum=)
  return unless finite_numeric?(last_val)

  target.maximum = last_val if target.respond_to?(:maximum=)
  target.exclusive_maximum = range.exclude_end? if target.respond_to?(:exclusive_maximum=)
end

.apply_to_schema(schema, range) ⇒ Object

Applies a Range to a schema as min/max or enum.

Parameters:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/grape_oas/range_utils.rb', line 52

def apply_to_schema(schema, range)
  bounds = [range.begin, range.end].compact
  return if bounds.empty?

  all_numeric = numeric_range?(range)
  any_numeric = bounds.any?(Numeric)
  mixed_numeric = any_numeric && !all_numeric
  numeric_range = all_numeric
  numeric_type = NUMERIC_TYPES.include?(schema.type)

  if mixed_numeric
    GrapeOAS.logger.warn("Mixed-type range #{range} ignored; endpoints must both be numeric or both non-numeric")
  elsif numeric_range && numeric_type
    apply_numeric_range(schema, range)
  elsif numeric_range
    GrapeOAS.logger.warn("Numeric range #{range} ignored on non-numeric schema type '#{schema.type}'")
  elsif !numeric_type
    expanded = expand_range_to_enum(range)
    schema.enum = expanded if expanded
  else
    GrapeOAS.logger.warn("Non-numeric range #{range} ignored on numeric schema type '#{schema.type}'")
  end
end

.expand_range_to_enum(range) ⇒ Object

Expands a non-numeric bounded Range to an enum array. Returns nil for numeric, unbounded, empty, or oversized ranges.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/grape_oas/range_utils.rb', line 11

def expand_range_to_enum(range)
  return nil if range.begin.nil? || range.end.nil?
  return nil if range.begin.is_a?(Numeric) || range.end.is_a?(Numeric)

  begin
    array = range.first(Constants::MAX_ENUM_RANGE_SIZE + 1)
  rescue TypeError
    return nil
  end

  return nil if array.empty? || array.size > Constants::MAX_ENUM_RANGE_SIZE

  array
end

.numeric_range?(range) ⇒ Boolean

Returns true when all non-nil bounds are Numeric (pure numeric range).

Returns:

  • (Boolean)


45
46
47
48
# File 'lib/grape_oas/range_utils.rb', line 45

def numeric_range?(range)
  bounds = [range.begin, range.end].compact
  bounds.any? && bounds.all?(Numeric)
end