infer-type 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d42e183dada37127aec852bd61db28217f0f3cd2
4
+ data.tar.gz: 4d7944e9b781eb03cdc2ecd60babec1a76c2394c
5
+ SHA512:
6
+ metadata.gz: 6bc5121ea29c3fbd4b5002f1f46d6a25a713edbc730c219766125e54747ddb730b1bc2a6cbd7bcca9871be704cd1f205abc9781751f47a6975df1ebdd8f0075a
7
+ data.tar.gz: 01a7fd3195f626a76c21e568d5bab630b6c01f5bd60e29ca1f792819b7e6502bed5ac7614d3cef1419e7509b07809dcfe1e51fe4a665974cbd0a6dbb0eeee023
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ # Base class for parsers
5
+ class Parser
6
+ class << self
7
+ # Method to specify or retrieve the type this parser detects
8
+ def detects(type = nil)
9
+ if type
10
+ raise ArgumentError, "detects cannot be String" if type == String
11
+ raise ArgumentError, "detects must be a Class" unless type.is_a?(Class)
12
+ @detects = type
13
+ end
14
+
15
+ @detects
16
+ end
17
+ end
18
+
19
+ # Subclasses must implement this method
20
+ def parse(_str)
21
+ raise NotImplementedError
22
+ end
23
+
24
+ private
25
+
26
+ # Methods to create success and failure results
27
+ def success(value)
28
+ InferType::Success.new(
29
+ value: value,
30
+ parser: self.class
31
+ )
32
+ end
33
+
34
+ def failure
35
+ InferType::Failure.new(parser: self.class)
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "date"
4
+
5
+ module InferType
6
+ module Parsers
7
+ class DateParser < InferType::Parser
8
+ detects Date
9
+
10
+ DATE_FORMAT = %r<
11
+ \A
12
+ (?<date>
13
+ (?<year> \d{4} ) -
14
+ (?<month> [0-1]\d ) -
15
+ (?<day> [0-3]\d )
16
+ )
17
+ \z
18
+ >x.freeze
19
+
20
+ def parse(str)
21
+ candidate = str.strip
22
+ return failure if candidate.empty?
23
+
24
+ # Looks like a Date
25
+ return failure unless match = candidate.match(DATE_FORMAT)
26
+
27
+ # Pre-validate to avoid Date.new being too lax
28
+
29
+ # Attempt to parse the date
30
+ year = match['year'].to_i
31
+ month = match['month'].to_i
32
+ day = match['day'].to_i
33
+ return failure unless Date.valid_date?(year, month, day)
34
+
35
+ # Attempt conversion
36
+ begin
37
+ value = Date.new(year, month, day)
38
+ return failure unless value.year == year && value.month == month && value.day == day
39
+ rescue ArgumentError
40
+ return failure
41
+ end
42
+
43
+ success(value)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ module Parsers
5
+ class FalseParser < InferType::Parser
6
+ detects FalseClass
7
+
8
+ FALSE_STRINGS = ['false', 'no', 'off', 'n'].freeze
9
+
10
+ # If true, only use the first false string
11
+ STRICT = true
12
+
13
+ # If true, case sensitive
14
+ CASE_SENSITIVE = false
15
+
16
+ def parse(str)
17
+ candidate = str.strip
18
+ candidate = candidate.downcase if !CASE_SENSITIVE
19
+ return failure if candidate.empty?
20
+
21
+ if STRICT
22
+ return success(false) if candidate == FALSE_STRINGS.first
23
+ else
24
+ return success(false) if FALSE_STRINGS.include?(candidate)
25
+ end
26
+
27
+ failure
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ module Parsers
5
+ class FloatParser < InferType::Parser
6
+ detects Float
7
+
8
+ # If false, "1" is NOT considered a Float (must be "1.0" etc.)
9
+ ALLOW_INTEGER = true
10
+
11
+ # Allow exponential notation like 1e3 or 1.5E-2
12
+ ALLOW_EXPONENTIAL = true
13
+
14
+ # Allow special values: NaN, Infinity
15
+ ALLOW_SPECIAL_VALUES = false
16
+
17
+ FLOAT_NO_EXP_REGEX = /\A[+-]?(?:\d+\.\d*|\.\d+)\z/
18
+ FLOAT_WITH_EXP_REGEX = /\A[+-]?(?:\d+(?:\.\d*)?|\.\d+)[eE][+-]?\d+\z/
19
+
20
+ def parse(str)
21
+ candidate = str.strip
22
+ return failure if candidate.empty?
23
+
24
+ # Check for exact special value string
25
+ if ["NaN", "Infinity", "-Infinity"].include?(candidate)
26
+ if ALLOW_SPECIAL_VALUES
27
+ return success(Float(candidate))
28
+ else
29
+ return failure
30
+ end
31
+ end
32
+
33
+ # Check for integer if allowed
34
+ if ALLOW_INTEGER
35
+ InferType::Parsers::IntegerParser.new.parse(candidate).tap do |result|
36
+ if result.parsed
37
+ # Return it as a float
38
+ return success(result.value.to_f)
39
+ end
40
+ end
41
+ end
42
+
43
+ # Check for float format
44
+ looks_float_no_exp = !candidate.match(FLOAT_NO_EXP_REGEX).nil?
45
+ looks_float_with_exp = ALLOW_EXPONENTIAL && !candidate.match(FLOAT_WITH_EXP_REGEX).nil?
46
+ looks_float = looks_float_no_exp || looks_float_with_exp
47
+
48
+ return failure unless looks_float
49
+
50
+ # Attempt conversion
51
+ begin
52
+ value = Float(candidate)
53
+ rescue ArgumentError
54
+ return failure
55
+ end
56
+
57
+ success(value)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ module Parsers
5
+ class IntegerParser < InferType::Parser
6
+ detects Integer
7
+
8
+ # Allow numbers with leading zeros like "00001" = 1
9
+ ALLOW_LEADING_ZERO = true
10
+
11
+ # Allow leading plus sign
12
+ ALLOW_LEADING_PLUS = true
13
+
14
+ INTEGER_REGEX = /\A-?\d+\z/
15
+
16
+ def parse(str)
17
+ candidate = str.strip
18
+ return failure if candidate.empty?
19
+
20
+ # Prepare the candidate for parsing
21
+ candidate = clean(candidate)
22
+
23
+ # Should now match integer format
24
+ return failure unless !candidate.match(INTEGER_REGEX).nil?
25
+
26
+ # Attempt conversion
27
+ begin
28
+ value = Integer(candidate, 10)
29
+ return failure unless value.to_s == candidate
30
+ rescue ArgumentError
31
+ return failure
32
+ end
33
+
34
+ success(value)
35
+ end
36
+
37
+ private
38
+
39
+ def clean(str)
40
+ clean = str.dup.strip
41
+ return clean if clean.empty?
42
+
43
+ # Remove leading +
44
+ if ALLOW_LEADING_PLUS
45
+ clean = clean.sub(/\A\+/, '')
46
+ end
47
+
48
+ # Preserve a single zero when the string is all zeros
49
+ if !clean.match(/\A-?0+\z/).nil?
50
+ return '0' # -0 is equivalent to 0
51
+ end
52
+
53
+ # Remove leading zeros
54
+ if ALLOW_LEADING_ZERO
55
+ clean = clean.sub(/\A(-)?0+/, '\1')
56
+ end
57
+
58
+ clean
59
+ end
60
+ end
61
+ end
62
+ end
63
+
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ module Parsers
5
+ class NilParser < InferType::Parser
6
+ detects NilClass
7
+
8
+ NIL_STRINGS = ['nil', 'null', 'nothing', 'undefined', 'none'].freeze
9
+
10
+ # If true, only use the first nil string
11
+ STRICT = true
12
+
13
+ # If true, case sensitive
14
+ CASE_SENSITIVE = false
15
+
16
+ def parse(str)
17
+ candidate = str.strip
18
+ candidate = candidate.downcase if !CASE_SENSITIVE
19
+ return failure if candidate.empty?
20
+
21
+ if STRICT
22
+ return success(nil) if candidate == NIL_STRINGS.first
23
+ else
24
+ return success(nil) if NIL_STRINGS.include?(candidate)
25
+ end
26
+
27
+ failure
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+ require "date"
5
+
6
+ module InferType
7
+ module Parsers
8
+ class TimeParser < InferType::Parser
9
+ detects Time
10
+
11
+ # If timezone offset is missing from a Time string, assume UTC
12
+ # If false, the system's local timezone will be used
13
+ DEFAULT_UTC = true
14
+
15
+ TIME_FORMAT = %r<
16
+ \A
17
+ (?<date>
18
+ (?<year> \d{4} ) -
19
+ (?<month> [0-1]\d ) -
20
+ (?<day> [0-3]\d )
21
+ )
22
+ (T|\s)
23
+ (?<time>
24
+ (?<hour> [0-2]\d ) \:
25
+ (?<minute> [0-5]\d )
26
+ (\:
27
+ (?<second> [0-5]\d )
28
+ ([\.,]
29
+ (?<subs> \d{1,9} )
30
+ )?
31
+ )?
32
+ )
33
+ (?<offset>
34
+ (?<sign> [+\-] )
35
+ (?<offh> [0-2]\d ) \:?
36
+ (?<offm> [0-5]\d )
37
+ |
38
+ (?<offz> Z | \s?UTC )
39
+ )?
40
+ \z
41
+ >x.freeze
42
+
43
+ def parse(str)
44
+ candidate = str.strip
45
+ return failure if candidate.empty?
46
+
47
+ # Looks like a Time
48
+ return failure unless match = candidate.match(TIME_FORMAT)
49
+
50
+ # Pre-validate to avoid Time.new being too lax
51
+
52
+ # Attempt to parse date
53
+ year = match['year'].to_i
54
+ month = match['month'].to_i
55
+ day = match['day'].to_i
56
+ return failure unless Date.valid_date?(year, month, day)
57
+
58
+ # Attempt to parse time
59
+ hour = match['hour'].to_i
60
+ minute = match['minute'].to_i
61
+ return failure unless hour.between?(0, 23) && minute.between?(0, 59)
62
+ if match['second']
63
+ second = match['second'].to_i
64
+ return failure unless second.between?(0, 59)
65
+ else
66
+ second = 0
67
+ end
68
+
69
+ # Add on subseconds if they were present
70
+ if match['subs']
71
+ begin
72
+ subs = ("0." + match['subs']).to_f
73
+ second += subs
74
+ rescue ArgumentError
75
+ return failure
76
+ end
77
+ end
78
+
79
+ # Was there an offset?
80
+ if match['offset'] && !match['offz']
81
+ sign = match['sign']
82
+ offh = match['offh'].to_i
83
+ offm = match['offm'].to_i
84
+ return failure unless (offh.between?(0, 13) && offm.between?(0, 59)) || (offh == 14 && offm == 0) # maximum 14 hour offsets
85
+ else
86
+ if DEFAULT_UTC || match['offz']
87
+ sign = "+"
88
+ offh = 0
89
+ offm = 0
90
+ end
91
+ end
92
+ if sign && offh && offm
93
+ offset = format("%<sign>s%<offh>02d:%<offm>02d", sign: sign, offh: offh, offm: offm)
94
+ else
95
+ offset = nil
96
+ end
97
+
98
+ # Attempt conversion
99
+ begin
100
+ args = [year, month, day, hour, minute, second]
101
+ args << offset if offset
102
+ value = Time.new(*args)
103
+ return failure unless value.year == year && value.mon == month && value.day == day
104
+ return failure unless value.hour == hour && value.min == minute
105
+ return failure unless second.to_r == value.sec + value.subsec
106
+ return failure unless value.utc_offset == (offh * 3600 + offm * 60) * (sign == "-" ? -1 : 1) if offset
107
+ rescue ArgumentError
108
+ return failure
109
+ end
110
+
111
+ success(value)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ module Parsers
5
+ class TrueParser < InferType::Parser
6
+ detects TrueClass
7
+
8
+ TRUE_STRINGS = ['true', 'yes', 'on', 'y'].freeze
9
+
10
+ # If true, only use the first true string
11
+ STRICT = true
12
+
13
+ # If true, case sensitive
14
+ CASE_SENSITIVE = false
15
+
16
+ def parse(str)
17
+ candidate = str.strip
18
+ candidate = candidate.downcase if !CASE_SENSITIVE
19
+ return failure if candidate.empty?
20
+
21
+ if STRICT
22
+ return success(true) if candidate == TRUE_STRINGS.first
23
+ else
24
+ return success(true) if TRUE_STRINGS.include?(candidate)
25
+ end
26
+
27
+ failure
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ class Registry
5
+ def initialize
6
+ @parsers = []
7
+ end
8
+
9
+ def parsers
10
+ @parsers.dup
11
+ end
12
+
13
+ def parser_for_type(type)
14
+ @parsers.find { |parser| parser.detects == type }
15
+ end
16
+
17
+ # Methods to manage parser registration
18
+ def register(parser_class)
19
+ validate_parser_class!(parser_class)
20
+
21
+ type = parser_class.detects
22
+ existing_index = @parsers.index { |parser| parser.detects == type }
23
+
24
+ if existing_index
25
+ old = @parsers[existing_index]
26
+ @parsers[existing_index] = parser_class
27
+ return old
28
+ end
29
+
30
+ # Last registered has lowest priority
31
+ @parsers << parser_class
32
+ nil
33
+ end
34
+
35
+ def deregister(parser_classes)
36
+ Array(parser_classes).each do |klass|
37
+ @parsers.delete(klass)
38
+ end
39
+ end
40
+
41
+ # Methods to manage parser priority
42
+ def prioritize(*items)
43
+ reorder(items, to_front: true)
44
+ end
45
+
46
+ def deprioritize(*items)
47
+ reorder(items, to_front: false)
48
+ end
49
+
50
+ private
51
+
52
+ # Ensure parser class being registered is valid
53
+ def validate_parser_class!(parser_class)
54
+ unless parser_class.is_a?(Class) && parser_class < InferType::Parser
55
+ raise ArgumentError, "Parser must subclass InferType::Parser"
56
+ end
57
+
58
+ type = parser_class.detects
59
+ raise ArgumentError, "Parser must declare the type it detects" if type.nil?
60
+
61
+ unless type.is_a?(Class) && !type.is_a?(String)
62
+ raise ArgumentError, "Parser must detect a Class (other than String)"
63
+ end
64
+
65
+ unless parser_class.instance_methods(false).include?(:parse)
66
+ raise ArgumentError, "Parser must define #parse(str)"
67
+ end
68
+
69
+ arity = parser_class.instance_method(:parse).arity
70
+ unless arity == 1 || arity == -2
71
+ raise ArgumentError, "#parse must accept exactly one argument"
72
+ end
73
+ end
74
+
75
+ # Normalize parser class or type to parser class
76
+ def normalize(items)
77
+ Array(items).map do |item|
78
+ if item.is_a?(Class) && item < InferType::Parser
79
+ item
80
+ elsif item.is_a?(Class)
81
+ parser = parser_for_type(item)
82
+ raise KeyError, "No parser registered for type #{item}" if parser.nil?
83
+ parser
84
+ else
85
+ raise ArgumentError, "Expected parser class or type class"
86
+ end
87
+ end
88
+ end
89
+
90
+ # Reorder parsers to front or back
91
+ def reorder(items, to_front:)
92
+ targets = normalize(items)
93
+ remaining = @parsers.reject { |p| targets.include?(p) }
94
+
95
+ @parsers =
96
+ if to_front
97
+ targets + remaining
98
+ else
99
+ remaining + targets
100
+ end
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module InferType
4
+ class Result
5
+ attr_reader :parsed, :value, :parser
6
+ def initialize(parsed: nil, value: nil, parser: nil)
7
+ @parsed = parsed
8
+ @value = value
9
+ @parser = parser
10
+ end
11
+ end
12
+
13
+ class Success < Result
14
+ def initialize(value: nil, parser: nil)
15
+ raise TypeError, "Parser returned a type other than the type it detects" if !value.is_a?(parser.detects)
16
+ super(parsed: true, value: value, parser: parser)
17
+ end
18
+ end
19
+
20
+ class Failure < Result
21
+ def initialize(parser: nil)
22
+ super(parsed: false, parser: parser)
23
+ end
24
+ end
25
+ end
26
+
data/lib/infer_type.rb ADDED
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "infer_type/result"
4
+ require_relative "infer_type/parser"
5
+ require_relative "infer_type/registry"
6
+
7
+ module InferType
8
+ class << self
9
+
10
+ # Whether to strip input strings before parsing
11
+ STRIP = true
12
+
13
+ # Primary method to parse a string into a type
14
+ def parse(_input, *allowed_types)
15
+ raise ArgumentError, "Can only parse Strings" unless _input.is_a?(String)
16
+
17
+ # Prepare the string
18
+ str = _input.dup
19
+ str = str.strip if STRIP
20
+
21
+ # Select appropriate parsers
22
+ parsers = select_parsers(allowed_types)
23
+
24
+ # Try each parser
25
+ parsers.each do |parser_class|
26
+ result = parser_class.new.parse(str)
27
+ raise TypeError, "Parser (#{parser_class}) must return a Result object using success(value) or failure() methods" unless result.is_a?(InferType::Result)
28
+ # Return as soon as one succeeds
29
+ return result.value if result.parsed
30
+ end
31
+
32
+ # All parsers failed: return the original input
33
+ _input
34
+ end
35
+
36
+ # Parser registration methods
37
+ def register(parser_class)
38
+ registry.register(parser_class)
39
+ end
40
+
41
+ def deregister(parser_classes)
42
+ registry.deregister(parser_classes)
43
+ end
44
+ alias unregister deregister
45
+
46
+ def prioritise(*items)
47
+ registry.prioritize(*items)
48
+ end
49
+ alias prioritize prioritise
50
+
51
+ def deprioritise(*items)
52
+ registry.deprioritize(*items)
53
+ end
54
+ alias deprioritize deprioritise
55
+ alias unprioritise deprioritise
56
+ alias unprioritize deprioritise
57
+
58
+ private
59
+
60
+ def registry
61
+ @registry ||= InferType::Registry.new
62
+ end
63
+
64
+ # Select parsers in priority order
65
+ def select_parsers(allowed_types)
66
+ all = registry.parsers
67
+ return all if allowed_types.empty?
68
+
69
+ # Allowed types have been specified
70
+ allowed_types = allowed_types.flatten
71
+ type_priority = {}
72
+
73
+ allowed_types.each_with_index do |type, index|
74
+ parser = registry.parser_for_type(type)
75
+ raise KeyError, "No parser registered for class #{type}" if parser.nil?
76
+ type_priority[type] = index
77
+ end
78
+
79
+ selected = all.select { |parser| type_priority.key?(parser.detects) }
80
+
81
+ # Override registry priority using allowed_types order
82
+ selected.sort_by { |parser| type_priority[parser.detects] }
83
+ end
84
+ end
85
+ end
86
+
87
+ # Load all built-in parsers
88
+ Dir.glob(File.join(__dir__, "infer_type/parsers/*.rb")).each do |file|
89
+ require_relative file
90
+ end
91
+
92
+ InferType.register(InferType::Parsers::IntegerParser)
93
+ InferType.register(InferType::Parsers::FloatParser)
94
+ InferType.register(InferType::Parsers::TrueParser)
95
+ InferType.register(InferType::Parsers::FalseParser)
96
+ InferType.register(InferType::Parsers::NilParser)
97
+ InferType.register(InferType::Parsers::DateParser)
98
+ InferType.register(InferType::Parsers::TimeParser)
99
+
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: infer-type
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Convincible
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-01-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.17.3
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.17'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.17.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: pry
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.14'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.14.1
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.14'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.14.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: pry-byebug
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.4'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 3.4.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.4'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 3.4.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: rspec
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '3.11'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.11.0
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.11'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 3.11.0
93
+ description: If a string is a representation of another class, such as "1", converts
94
+ it to that other class. Works for basic Ruby types and can be extended.
95
+ email:
96
+ - development@convincible.media
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - lib/infer_type.rb
102
+ - lib/infer_type/parser.rb
103
+ - lib/infer_type/parsers/date.rb
104
+ - lib/infer_type/parsers/false.rb
105
+ - lib/infer_type/parsers/float.rb
106
+ - lib/infer_type/parsers/integer.rb
107
+ - lib/infer_type/parsers/nil.rb
108
+ - lib/infer_type/parsers/time.rb
109
+ - lib/infer_type/parsers/true.rb
110
+ - lib/infer_type/registry.rb
111
+ - lib/infer_type/result.rb
112
+ homepage: https://github.com/ConvincibleMedia/infer-type
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: 2.1.0
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.2.0
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Convert strings to other classes by inference.
136
+ test_files: []