File: numeric.rb

package info (click to toggle)
ruby-necromancer 0.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 308 kB
  • sloc: ruby: 1,578; sh: 4; makefile: 4
file content (92 lines) | stat: -rw-r--r-- 2,584 bytes parent folder | download
1
2
3
4
5
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
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# frozen_string_literal: true

require_relative "../converter"
require_relative "../null_converter"

module Necromancer
  # Container for Numeric converter classes
  module NumericConverters
    INTEGER_MATCHER = /^\s*[-+]?\s*(\d[\d\s]*)?$/.freeze

    FLOAT_MATCHER = /^\s*[-+]?([\d\s]*)(\.[\d\s]+)?([eE]?[-+]?[\d\s]+)?$/.freeze

    # An object that converts a String to an Integer
    class StringToIntegerConverter < Converter
      # Convert string value to integer
      #
      # @example
      #   converter.call("1abc")  # => 1
      #
      # @api public
      def call(value, strict: config.strict)
        Integer(value)
      rescue StandardError
        strict ? raise_conversion_type(value) : value.to_i
      end
    end

    # An object that converts an Integer to a String
    class IntegerToStringConverter < Converter
      # Convert integer value to string
      #
      # @example
      #   converter.call(1)  # => "1"
      #
      # @api public
      def call(value, **_)
        value.to_s
      end
    end

    # An object that converts a String to a Float
    class StringToFloatConverter < Converter
      # Convert string to float value
      #
      # @example
      #   converter.call("1.2") # => 1.2
      #
      # @api public
      def call(value, strict: config.strict)
        Float(value)
      rescue StandardError
        strict ? raise_conversion_type(value) : value.to_f
      end
    end

    # An object that converts a String to a Numeric
    class StringToNumericConverter < Converter
      # Convert string to numeric value
      #
      # @example
      #   converter.call("1.0")  # => 1.0
      #
      # @example
      #   converter.call("1")   # => 1
      #
      # @api public
      def call(value, strict: config.strict)
        case value
        when INTEGER_MATCHER
          StringToIntegerConverter.new(:string, :integer).(value, strict: strict)
        when FLOAT_MATCHER
          StringToFloatConverter.new(:string, :float).(value, strict: strict)
        else
          strict ? raise_conversion_type(value) : value
        end
      end
    end

    def self.load(conversions)
      [
        StringToIntegerConverter.new(:string, :integer),
        IntegerToStringConverter.new(:integer, :string),
        NullConverter.new(:integer, :integer),
        StringToFloatConverter.new(:string, :float),
        NullConverter.new(:float, :float),
        StringToNumericConverter.new(:string, :numeric)
      ].each do |converter|
        conversions.register converter
      end
    end
  end # Conversion
end # Necromancer