Module: Conversion

Defined in:
lib/conversion/core.rb,
lib/conversion/version.rb,
lib/conversion/accessors.rb,
lib/conversion/mode/weak.rb,
lib/conversion/mode/stable_nil.rb,
lib/conversion/mode/nil_on_failure.rb,
lib/conversion/mode/human_input/core.rb,
lib/conversion/mode/strong_type_checking.rb

Overview

:nodoc:

Defined Under Namespace

Modules: Accessors, EnumerableConverter, HumanInputString, VERSION

Class Method Summary collapse

Class Method Details

.base_converter(target) ⇒ Object

You’re not supposed to call this method. Use Conversion.converter or Conversion.entries_converter instead.

Returns a Proc that is the default converter to target.

  • If target is nil, returns nil

  • If target responds to :to_proc, returns target.to_proc

  • If target is a String, raise TypeError

  • If target is a Symbol, returns a Proc that send the target message to its parameter

  • If target is a Class, returns a Proc that creates a new object from its parameters



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/conversion/core.rb', line 268

def base_converter(target)
  converter = 
#        if target.respond_to?(:to_converter_proc)
#          target.to_converter_proc
#      
#        elsif target.nil?
    if target.nil?
      nil
  
    elsif target.respond_to?(:to_proc)
      target.to_proc
  
    elsif target.is_a?(String)
      raise TypeError.new("Strings can't be coerced into Proc")
  
    elsif target.is_a?(Symbol)
      proc { |value| value.send(target) }
  
    elsif target.is_a?(Class) &&
          target.respond_to?(:new) &&
          target.method(:new).arity != 0
      proc { |*value|
        if value.length == 1 && value.first.is_a?(target)
          value.first
        else
          target.new(*value)
        end
      }
    end

  converter || raise(ArgumentError.new("#{target.inspect} can't be coerced into Proc"))
end

.converter(target, options = {}) ⇒ Object

Builds a converter Proc that converts to target, with options.

Default converter is returned unless options contains a :mode (see Conversion.base_converter), and ArgumentError si raised if :mode is unsupported.

Precisely, if target has a “to_#mode_converter_proc” method, it is used (see Integer.to_converter_proc, Date.to_human_input_converter_proc).

Else, if Conversion has a “#mode_converter” method, it is used (see Conversion.weak_converter).

See also: Object#convert_to



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/conversion/core.rb', line 225

def converter(target, options={})
  mode = options[:mode]
  begin
    target_mode = (mode == :base) ? nil : mode
    target_builder = ['to', target_mode, 'converter_proc'].compact.join('_')
    return target.send(target_builder)
  rescue NoMethodError
    begin
      converter_mode = (mode.nil?) ? 'base' : mode.to_s
      converter_builder = converter_mode+'_converter'
      proc = send(converter_builder, target)
    rescue NoMethodError
      raise ArgumentError.new("#{options[:mode].inspect} is not a valid conversion mode")
    end
    
    begin
      target.singleton_class.instance_eval { define_method(target_builder) { proc } }
    rescue TypeError
      # target.singleton_class.instance_eval fails for some instances, like symbols
    end
    
    proc
  end
end

.entries_converter(target, options = {}) ⇒ Object

Builds an enumerable converter Proc that converts to target, with options.

Default converter is returned unless options contains a :mode (see Conversion.base_converter), and ArgumentError is raised if :mode is unsupported.

See also: Conversion.converter, Object#convert_entries_to



255
256
257
# File 'lib/conversion/core.rb', line 255

def entries_converter(target, options={})
  converter(target, options).convert_to(Conversion::EnumerableConverter)
end

.human_input_converter(target) ⇒ Object

You’re not supposed to call this method. Use Conversion.converter or Conversion.entries_converter instead.

This method implements the :human_input conversion mode.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/conversion/mode/human_input/core.rb', line 6

def human_input_converter(target)
  base_converter = converter(target, :mode=>:weak)

  return base_converter unless
    base_converter &&
    target.is_a?(Class)

  proc do |value|
    value = value.convert_to(Conversion::HumanInputString)
    if value.nil? || value.empty?
      nil
    else
      value = value.gsub(',','.').gsub(/ /,'') if value =~ /^[-+]?[ \d]*[\.,]?\d+$/
      base_converter.call(value)
    end
  end
end

.nil_on_failure_converter(target) ⇒ Object

You’re not supposed to call this method. Use Conversion.converter or Conversion.entries_converter instead.

This method implements the :nil_on_failure conversion mode.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/conversion/mode/nil_on_failure.rb', line 6

def nil_on_failure_converter(target)
  base_converter = converter(target)

  return nil unless base_converter
  
  if target.is_a?(Class)
    proc do |value|
      begin
        result = base_converter.call(value)
        result = nil unless result.is_a?(target)
      rescue Exception
        result = nil
      end
      result
    end
  else
    proc do |value|
      begin
        base_converter.call(value)
      rescue Exception
        nil
      end
    end
  end
end

.stable_nil_converter(target) ⇒ Object

You’re not supposed to call this method. Use Conversion.converter or Conversion.entries_converter instead.

This method implements the :stable_nil conversion mode.



6
7
8
9
10
11
12
13
14
15
16
# File 'lib/conversion/mode/stable_nil.rb', line 6

def stable_nil_converter(target)
  base_converter = converter(target)
  return nil unless base_converter
  proc do |value|
    if value.nil?
      nil
    else
      base_converter.call(value)
    end
  end
end

.strong_type_checking_converter(target) ⇒ Object

You’re not supposed to call this method. Use Conversion.converter or Conversion.entries_converter instead.

This method implements the :strong_type_checking conversion mode.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/conversion/mode/strong_type_checking.rb', line 6

def strong_type_checking_converter(target)
  base_converter = converter(target)

  return base_converter unless
    base_converter &&
    target.is_a?(Class)

  proc do |value|
    if value.nil?
      nil
    else
    raise ArgumentError.new("Invalid value for #{target}: #{value.inspect}") unless value.is_a?(target)
      value
   end
  end
end

.weak_converter(target) ⇒ Object

You’re not supposed to call this method. Use Conversion.converter or Conversion.entries_converter instead.

This method implements the :weak conversion mode.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/conversion/mode/weak.rb', line 6

def weak_converter(target)
  base_converter = converter(target)

  return nil unless base_converter
  
  if target.is_a?(Class)
    proc do |value|
      begin
        result = base_converter.call(value)
        result = value unless result.is_a?(target)
      rescue Exception
        result = value
      end
      result
    end
  else
    proc do |value|
      begin
        base_converter.call(value)
      rescue Exception
        value
      end
    end
  end
end