types 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 220aa1748f5f534bf7f658baf0aa65a07b699c97ae8267cf4e5da08e2958159b
4
+ data.tar.gz: 9693de18eaf9afb2960cae708589869ef66f6be626db835cb24dffd56664ba93
5
+ SHA512:
6
+ metadata.gz: 9a29b004b8e2a61e8f1e56b8fe7e698b36bdaa4f155920b0eae6ad7f64ee974fdb1491703be3b82b583b93fa0bc926a3c4cd888b684fd1dc983c1107365685d6
7
+ data.tar.gz: 2b7fbe1429c936cb15ffe8854aaab3aa4f7f9079db008453815bb2ff45d5e4bdf854753984be6e5e1533d281a171eb5880e4698db5ea58ae0812c6167a7ac2fb
checksums.yaml.gz.sig ADDED
Binary file
data/lib/types/any.rb ADDED
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Types
24
+ # An ordered list of types. The first type to match the input is used.
25
+ #
26
+ # ```ruby
27
+ # type = Bake::Types::Any(Bake::Types::String, Bake::Types::Integer)
28
+ # ```
29
+ #
30
+ class Any
31
+ # Initialize the instance with an array of types.
32
+ # @parameter types [Array] the array of types.
33
+ def initialize(types)
34
+ @types = types
35
+ end
36
+
37
+ # Create a copy of the current instance with the other type appended.
38
+ # @parameter other [Type] the type instance to append.
39
+ def | other
40
+ self.class.new([*@types, other])
41
+ end
42
+
43
+ # Whether any of the listed types is a composite type.
44
+ # @returns [Boolean] true if any of the listed types is `composite?`.
45
+ def composite?
46
+ @types.any?{|type| type.composite?}
47
+ end
48
+
49
+ # Parse an input string, trying the listed types in order, returning the first one which doesn't raise an exception.
50
+ # @parameter input [String] the input to parse, e.g. `"5"`.
51
+ def parse(input)
52
+ @types.each do |type|
53
+ return type.parse(input)
54
+ rescue => error
55
+ last_error = error
56
+ end
57
+
58
+ if last_error
59
+ raise last_error
60
+ else
61
+ raise ArgumentError, "Unable to parse input #{input.inspect}!"
62
+ end
63
+ end
64
+
65
+ # As a class type, accepts any value.
66
+ def self.parse(value)
67
+ value
68
+ end
69
+
70
+ # Generate a readable string representation of the listed types.
71
+ def to_s
72
+ "#{@types.join(' | ')}"
73
+ end
74
+ end
75
+
76
+ # A type constructor.
77
+ #
78
+ # ```ruby
79
+ # Any(Integer, String)
80
+ # ```
81
+ #
82
+ # See [Any.initialize](#Bake::Types::Any::initialize).
83
+ #
84
+ def self.Any(*types)
85
+ Any.new(types)
86
+ end
87
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ class Array
27
+ include Generic
28
+
29
+ def initialize(item_type)
30
+ @item_type = item_type
31
+ end
32
+
33
+ def composite?
34
+ true
35
+ end
36
+
37
+ def map(values)
38
+ values.map{|value| @item_type.parse(value)}
39
+ end
40
+
41
+ def parse(input)
42
+ case input
43
+ when ::String
44
+ return parse_values(parse_string(input))
45
+ when ::Array
46
+ return parse_values(input)
47
+ else
48
+ raise ArgumentError, "Cannot coerce #{input.inspect} into Array!"
49
+ end
50
+ end
51
+
52
+ def to_s
53
+ "Array(#{@item_type})"
54
+ end
55
+
56
+ private
57
+
58
+ def parse_string(input)
59
+ ::JSON.parse("[#{input}]")
60
+ end
61
+
62
+ def parse_values(input)
63
+ input.map{|value, index| @item_type.parse(value)}
64
+ end
65
+ end
66
+
67
+ def self.Array(item_type = Any)
68
+ Array.new(item_type)
69
+ end
70
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'method'
24
+
25
+ module Types
26
+ class Block
27
+ include Generic
28
+
29
+ def initialize(argument_types, return_type)
30
+ @argument_types = argument_types
31
+ @return_type = return_type
32
+ end
33
+
34
+ attr :argument_types
35
+ attr :return_type
36
+
37
+ def composite?
38
+ true
39
+ end
40
+
41
+ def to_s
42
+ if @return_type
43
+ "Block(#{@argument_types.join(', ')}, returns: #{@return_type})"
44
+ else
45
+ "Block(#{@argument_types.join(', ')})"
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.Block(*argument_types, returns: nil)
51
+ Block.new(argument_types, returns)
52
+ end
53
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ module Boolean
27
+ extend Generic
28
+
29
+ def self.parse(input)
30
+ if input =~ /t(rue)?|y(es)?/i
31
+ return true
32
+ elsif input =~ /f(alse)?|n(o)?/i
33
+ return false
34
+ else
35
+ raise ArgumentError, "Cannot coerce #{input.inspect} into Boolean!"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ class Class
27
+ extend Generic
28
+ include Generic
29
+
30
+ def initialize(base)
31
+ @base = base
32
+ end
33
+
34
+ attr :base
35
+
36
+ def composite?
37
+ true
38
+ end
39
+
40
+ def parse(input)
41
+ klass = Object.const_get(input)
42
+
43
+ if @base and !klass.ancestors.include?(@base)
44
+ raise ArgumentError, "Class #{klass} is not a subclass of #{@base}!"
45
+ end
46
+
47
+ return klass
48
+ end
49
+
50
+ def self.composite?
51
+ false
52
+ end
53
+
54
+ def self.parse(input)
55
+ klass = Object.const_get(input)
56
+
57
+ if !klass.is_a?(::Class)
58
+ raise ArgumentError, "Class #{klass} is not a Class!"
59
+ end
60
+
61
+ return klass
62
+ end
63
+ end
64
+
65
+ def self.Class(base = Object)
66
+ Class.new(base)
67
+ end
68
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ require 'bigdecimal'
26
+
27
+ module Types
28
+ module Decimal
29
+ extend Generic
30
+
31
+ def self.parse(input)
32
+ case input
33
+ when ::Float
34
+ BigDecimal(input, ::Float::DIG+1)
35
+ else
36
+ BigDecimal(input)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ module Float
27
+ extend Generic
28
+
29
+ def self.parse(input)
30
+ Float(input)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'any'
24
+
25
+ module Types
26
+ # An extension module which allows constructing `Any` types using the `|` operator.
27
+ module Generic
28
+ # Create an instance of `Any` with the arguments as types.
29
+ # @parameter other [Type] the alternative type to match.
30
+ def | other
31
+ Any.new([self, other])
32
+ end
33
+
34
+ # Whether a type contains nested types or not.
35
+ def composite?
36
+ false
37
+ end
38
+
39
+ def to_s
40
+ self.name.rpartition('::').last
41
+ end
42
+ end
43
+ end
data/lib/types/hash.rb ADDED
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ class Hash
27
+ include Generic
28
+
29
+ def initialize(key_type, value_type)
30
+ @key_type = key_type
31
+ @value_type = value_type
32
+ end
33
+
34
+ def composite?
35
+ true
36
+ end
37
+
38
+ def parse(input)
39
+ case input
40
+ when ::String
41
+ return parse_values(parse_string(input))
42
+ when ::Hash
43
+ return parse_values(input)
44
+ else
45
+ raise ArgumentError, "Cannot coerce #{input.inspect} into Hash!"
46
+ end
47
+ end
48
+
49
+ def to_s
50
+ "Hash(#{@key_type}, #{@value_type})"
51
+ end
52
+
53
+ private
54
+
55
+ def parse_string(input)
56
+ ::JSON.parse("{#{input}}")
57
+ end
58
+
59
+ def parse_values(input)
60
+ input.map{|key, value| [@key_type.parse(key), @value_type.parse(value)]}.to_h
61
+ end
62
+ end
63
+
64
+ def self.Hash(key_type, value_type)
65
+ Hash.new(key_type, value_type)
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ module Integer
27
+ extend Generic
28
+
29
+ def self.parse(input)
30
+ Integer(input)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ # A lambda that represents a function (or callable object).
27
+ class Lambda
28
+ include Generic
29
+
30
+ def initialize(argument_types, return_type)
31
+ @argument_types = argument_types
32
+ @return_type = return_type
33
+ end
34
+
35
+ attr :argument_types
36
+ attr :return_type
37
+
38
+ def composite?
39
+ true
40
+ end
41
+
42
+ def to_s
43
+ if @return_type
44
+ "Lambda(#{@argument_types.join(', ')}, returns: #{@return_type})"
45
+ else
46
+ "Lambda(#{@argument_types.join(', ')})"
47
+ end
48
+ end
49
+
50
+ def parse(input)
51
+ case input
52
+ when ::String
53
+ eval("lambda{#{input}}", TOPLEVEL_BINDING)
54
+ when ::Proc
55
+ input
56
+ else
57
+ raise ArgumentError, "Cannot coerce #{input.inpsect} into Lambda!"
58
+ end
59
+ end
60
+ end
61
+
62
+ def self.Lambda(*argument_types, returns: nil)
63
+ Lambda.new(argument_types, returns)
64
+ end
65
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright, 2020, by Samuel G. D. Williams. <http://www.codeotaku.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative 'generic'
24
+
25
+ module Types
26
+ # A method type attached to a receiver type.
27
+ class Method
28
+ include Generic
29
+
30
+ def initialize(receiver_type, argument_types, return_type)
31
+ @receiver_type = receiver_type
32
+ @argument_types = argument_types
33
+ @return_type = return_type
34
+ end
35
+
36
+ attr :receiver_type
37
+ attr :argument_types
38
+ attr :return_type
39
+
40
+ def composite?
41
+ true
42
+ end
43
+
44
+ def to_s
45
+ buffer = ::String.new
46
+
47
+ if @argument_types&.any?
48
+ buffer << "Method(#{@receiver_type}, #{@argument_types.join(', ')}"
49
+ else
50
+ buffer << "Method(#{@receiver_type}, "
51
+ end
52
+
53
+ if @return_type
54
+ buffer << "returns: #{@return_type})"
55
+ else
56
+ buffer << ")"
57
+ end
58
+
59
+ return buffer
60
+ end
61
+
62
+ def parse(input)
63
+ case input
64
+ when ::String
65
+ receiver_type.instance_method(input)
66
+ when ::Proc
67
+ input
68
+ else
69
+ raise ArgumentError, "Cannot coerce #{input.inpsect} into Method!"
70
+ end
71
+ end
72
+ end
73
+
74
+ def self.Method(receiver_type, *argument_types, returns: nil)
75
+ Method.new(receiver_type, argument_types, returns)
76
+ end
77
+ end