Class: Lens::Rails::Sanitizer

Inherits:
Object
  • Object
show all
Defined in:
lib/lens/rails/sanitizer.rb

Constant Summary collapse

BASIC_OBJECT =
"#<BasicObject>".freeze
DEPTH =
"[DEPTH]".freeze
RAISED =
"[RAISED]".freeze
RECURSION =
"[RECURSION]".freeze
TRUNCATED =
"[TRUNCATED]".freeze
MAX_STRING =
65_536

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_depth: 20) ⇒ Sanitizer

Returns a new instance of Sanitizer.



22
23
24
# File 'lib/lens/rails/sanitizer.rb', line 22

def initialize(max_depth: 20)
  @max_depth = max_depth
end

Class Method Details

.sanitize(data) ⇒ Object



17
18
19
20
# File 'lib/lens/rails/sanitizer.rb', line 17

def self.sanitize(data)
  @instance ||= new
  @instance.sanitize(data)
end

Instance Method Details

#sanitize(data, depth = 0, stack = nil) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/lens/rails/sanitizer.rb', line 26

def sanitize(data, depth = 0, stack = nil)
  return BASIC_OBJECT if basic_object?(data)

  if recursive?(data)
    return RECURSION if stack&.include?(data.object_id)
    stack = stack ? stack.dup : Set.new
    stack << data.object_id
  end

  case data
  when Hash
    return DEPTH if depth >= @max_depth
    data.each_with_object({}) do |(k, v), h|
      h[k.is_a?(Symbol) ? k : sanitize(k, depth + 1, stack)] = sanitize(v, depth + 1, stack)
    end
  when Array, Set
    return DEPTH if depth >= @max_depth
    data.to_a.map { |v| sanitize(v, depth + 1, stack) }
  when Numeric, TrueClass, FalseClass, NilClass
    data
  when String
    sanitize_string(data)
  else
    klass = data.class
    begin
      str = String(data)
    rescue
      return RAISED
    end
    return "#<#{klass.name}>" if str.include?("#<") && str.include?(">")
    sanitize_string(str)
  end
end