Class: Mutations::OutcomeHashFilter

Inherits:
InputFilter
  • Object
show all
Defined in:
lib/mutations/outcome_hash_filter.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}, &block) ⇒ OutcomeHashFilter

Returns a new instance of OutcomeHashFilter.



20
21
22
23
24
25
26
27
28
# File 'lib/mutations/outcome_hash_filter.rb', line 20

def initialize(opts = {}, &block)
  super(opts)

  @optional_outputs = {}
  @current_outputs = @required_outputs = {}
  @outcome_descriptions = {}

  instance_eval(&block) if block_given?
end

Instance Attribute Details

#optional_outputsObject

Returns the value of attribute optional_outputs.



18
19
20
# File 'lib/mutations/outcome_hash_filter.rb', line 18

def optional_outputs
  @optional_outputs
end

#outcome_descriptionObject

Returns the value of attribute outcome_description.



18
19
20
# File 'lib/mutations/outcome_hash_filter.rb', line 18

def outcome_description
  @outcome_description
end

#outcome_descriptionsObject

Returns the value of attribute outcome_descriptions.



18
19
20
# File 'lib/mutations/outcome_hash_filter.rb', line 18

def outcome_descriptions
  @outcome_descriptions
end

#required_outputsObject

Returns the value of attribute required_outputs.



18
19
20
# File 'lib/mutations/outcome_hash_filter.rb', line 18

def required_outputs
  @required_outputs
end

Class Method Details

.register_additional_filter(type_class, type_name) ⇒ Object



3
4
5
6
7
8
9
10
11
12
# File 'lib/mutations/outcome_hash_filter.rb', line 3

def self.register_additional_filter(type_class, type_name)
  define_method(type_name) do |*args, &block|
    name = args[0]
    options = args[1] || {}

    @outcome_descriptions[name.to_sym] = current_outcome_description || 'N/A'

    @current_outputs[name.to_sym] = type_class.new(options, &block)
  end
end

Instance Method Details

#array(name, options = {}, &block) ⇒ Object



77
78
79
80
# File 'lib/mutations/outcome_hash_filter.rb', line 77

def array(name, options = {}, &block)
  name_sym = name.to_sym
  @current_outputs[name.to_sym] = ArrayFilter.new(name_sym, options, &block)
end

#current_outcome_descriptionObject



45
46
47
48
49
# File 'lib/mutations/outcome_hash_filter.rb', line 45

def current_outcome_description
  (@outcome_description && @outcome_description.dup).tap do
    @outcome_description = nil
  end
end

#desc(outcome_description) ⇒ Object



41
42
43
# File 'lib/mutations/outcome_hash_filter.rb', line 41

def desc(outcome_description)
  @outcome_description = outcome_description
end

#dupObject



30
31
32
33
34
35
36
37
38
39
# File 'lib/mutations/outcome_hash_filter.rb', line 30

def dup
  dupped = OutcomeHashFilter.new
  @optional_outputs.each_pair do |k, v|
    dupped.optional_outputs[k] = v
  end
  @required_outputs.each_pair do |k, v|
    dupped.required_outputs[k] = v
  end
  dupped
end

#filter(data) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/mutations/outcome_hash_filter.rb', line 82

def filter(data)
  # Handle nil case
  return (options[:nils] ? [nil, nil] : [nil, :nils]) if data.nil?

  # Ensure it's a hash
  return [data, :hash] unless data.is_a?(Hash)

  # We always want a hash with indiffernet access
  data = data.with_indifferent_access unless data.is_a?(HashWithIndifferentAccess)

  errors = ErrorHash.new
  filtered_data = HashWithIndifferentAccess.new
  wildcard_filterer = nil

  [[@required_outputs, true], [@optional_outputs, false]].each do |(outputs, is_required)|
    outputs.each_pair do |key, filterer|
      # If we are doing wildcards, then record so and move on
      if key == :*
        wildcard_filterer = filterer
        next
      end

      data_element = data[key]

      if data.key?(key)
        sub_data, sub_error = filterer.filter(data_element)

        case
        when sub_error.nil? then filtered_data[key] = sub_data
        when !is_required && filterer.discard_invalid? then data.delete(key)
        when !is_required && sub_error == :empty && filterer.discard_empty? then data.delete(key)
        when !is_required && sub_error == :nils && filterer.discard_nils? then data.delete(key)
        else
          sub_error = ErrorAtom.new(key, sub_error) if sub_error.is_a?(Symbol)
          errors[key] = sub_error
        end
        next
      end

      if filterer.has_default?
        filtered_data[key] = filterer.default
      elsif is_required
        errors[key] = ErrorAtom.new(key, :required)
      end
    end
  end

  if wildcard_filterer
    filtered_keys = data.keys - filtered_data.keys

    filtered_keys.each do |key|
      data_element = data[key]

      sub_data, sub_error = wildcard_filterer.filter(data_element)
      case
      when sub_error.nil? then filtered_data[key] = sub_data
      when wildcard_filterer.discard_invalid? then data.delete(key)
      when sub_error == :empty && wildcard_filterer.discard_empty? then data.delete(key)
      when sub_error == :nils && wildcard_filterer.discard_nils? then data.delete(key)
      else
        sub_error = ErrorAtom.new(key, sub_error) if sub_error.is_a?(Symbol)
        errors[key] = sub_error
      end
    end
  end

  errors.any? ? [data, errors] : [filtered_data, nil]
end

#hash(name, options = {}, &block) ⇒ Object



69
70
71
# File 'lib/mutations/outcome_hash_filter.rb', line 69

def hash(name, options = {}, &block)
  @current_outputs[name.to_sym] = OutcomeHashFilter.new(options, &block)
end

#model(name, options = {}) ⇒ Object



73
74
75
# File 'lib/mutations/outcome_hash_filter.rb', line 73

def model(name, options = {})
  @current_outputs[name.to_sym] = ModelFilter.new(name.to_sym, options)
end

#outcome_optional(&block) ⇒ Object



56
57
58
59
# File 'lib/mutations/outcome_hash_filter.rb', line 56

def outcome_optional(&block)
  @current_outputs = @optional_outputs
  instance_eval(&block)
end

#outcome_optional_keysObject



65
66
67
# File 'lib/mutations/outcome_hash_filter.rb', line 65

def outcome_optional_keys
  @optional_outputs.keys
end

#outcome_required(&block) ⇒ Object



51
52
53
54
# File 'lib/mutations/outcome_hash_filter.rb', line 51

def outcome_required(&block)
  @current_outputs = @required_outputs
  instance_eval(&block)
end

#outcome_required_keysObject



61
62
63
# File 'lib/mutations/outcome_hash_filter.rb', line 61

def outcome_required_keys
  @required_outputs.keys
end