litl 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.
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LIT
4
+ # @api private
5
+ # @since 0.1.0
6
+ class TypeChecker
7
+ AST = Parser::AST
8
+ PRIMITIVE_TYPE_NAMESPACE = "AST::Type::Primitive"
9
+
10
+ def initialize(mod)
11
+ @mod = mod
12
+ end
13
+
14
+ def check_type!(type, value)
15
+ is_primitive =
16
+ if type.is_a?(Module)
17
+ type.name.include?(PRIMITIVE_TYPE_NAMESPACE)
18
+ else
19
+ type.class.name.include?(PRIMITIVE_TYPE_NAMESPACE)
20
+ end
21
+
22
+ if is_primitive
23
+ check_primitive_type!(type, value)
24
+ elsif type.is_a?(AST::Type::Alias)
25
+ check_type_alias!(type.name, value)
26
+ else
27
+ raise InvalidTypeError, "invalid type: #{type}"
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ # rubocop:disable Metrics/MethodLength
34
+ def check_primitive_type!(type, value)
35
+ if type == AST::Type::Primitive::String
36
+ unless value.is_a?(String)
37
+ raise TypeError, "expected #{value} to be a String"
38
+ end
39
+ elsif type == AST::Type::Primitive::Integer
40
+ unless value.is_a?(Integer)
41
+ raise TypeError, "expected #{value} to be an Integer"
42
+ end
43
+ elsif type == AST::Type::Primitive::Float
44
+ unless value.is_a?(Float)
45
+ raise TypeError, "expected #{value} to be a Float"
46
+ end
47
+ elsif type == AST::Type::Primitive::Boolean
48
+ unless value == true || value == false
49
+ raise TypeError, "expected #{value} to be a Boolean"
50
+ end
51
+ elsif type.is_a?(AST::Type::Primitive::Option)
52
+ if value.is_a?(::LIT::Object::Option::Some)
53
+ check_primitive_type!(type.type, value.value)
54
+ elsif value == ::LIT::Object::Option::None
55
+ # ok
56
+ else
57
+ raise TypeError, "expected #{value} to be an instance of Option"
58
+ end
59
+ elsif type.is_a?(AST::Type::Primitive::Array)
60
+ if value.is_a?(::LIT::Object::Array)
61
+ value.each { |v| check_primitive_type!(type.type, v) }
62
+ else
63
+ raise TypeError, "expected #{value} to be an array"
64
+ end
65
+ elsif type.is_a?(AST::Type::Primitive::Map)
66
+ if value.is_a?(::LIT::Object::Map)
67
+ value.values.each do |(k, v)|
68
+ check_primitive_type!(type.key_type, k)
69
+ check_primitive_type!(type.value_type, v)
70
+ end
71
+ else
72
+ raise TypeError, "expected #{value} to be a Map"
73
+ end
74
+ elsif type.is_a?(AST::Type::Alias)
75
+ check_type_alias!(type.name, value)
76
+ else
77
+ raise InvalidTypeError, "invalid primitive type: #{type}"
78
+ end
79
+ end
80
+ # rubocop:enable Metrics/MethodLength
81
+
82
+ def check_type_alias!(name, value)
83
+ const = @mod.const_get(name)
84
+
85
+ if const <= Object::Enum
86
+ unless value.respond_to?(:__parent__) && value.__parent__ == const
87
+ raise TypeError, "expected #{value} to be of type #{name}"
88
+ end
89
+ elsif const <= Object::Struct
90
+ # ok (checked upon struct initialization)
91
+ elsif const <= Object::Option
92
+ type = const.const_get("TYPE")
93
+ check_type!(type, value)
94
+ elsif const <= Object::Map
95
+ type = const.const_get("TYPE")
96
+ check_type!(type, value)
97
+ elsif const <= Object::Array
98
+ type = const.const_get("TYPE")
99
+ check_type!(type, value)
100
+ else
101
+ type = const.const_get("TYPE")
102
+ check_primitive_type!(type, value)
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LIT
4
+ # @api private
5
+ # @since 0.1.0
6
+ module Utils
7
+ def self.camelize(string)
8
+ string.to_s.split("_").collect(&:capitalize).join
9
+ end
10
+
11
+ # @api private
12
+ # @since 0.1.0
13
+ class MapHash
14
+ attr_reader :values
15
+
16
+ def initialize(values)
17
+ @values = values.transform_keys { |k| k.is_a?(Symbol) ? k.to_s : k }
18
+ end
19
+
20
+ def [](key)
21
+ key = key.is_a?(Symbol) ? key.to_s : key
22
+ @values[key]
23
+ end
24
+
25
+ def each(&block)
26
+ @values.each(&block)
27
+ end
28
+
29
+ def to_h
30
+ @values
31
+ end
32
+ end
33
+
34
+ # @api private
35
+ # @since 0.1.0
36
+ def self.const_reset(mod, const_name, const_value)
37
+ if mod.const_defined?(const_name, false)
38
+ mod.send(:remove_const, const_name)
39
+ end
40
+
41
+ mod.const_set(const_name, const_value)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LIT
4
+ # @return [String]
5
+ #
6
+ # @api public
7
+ # @since 0.1.0
8
+ VERSION = "0.1.0"
9
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/lit/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
7
+
8
+ spec.name = "litl"
9
+ spec.version = LIT::VERSION
10
+ spec.authors = %w[Alexander Komarov]
11
+ spec.email = %w[ak@akxcv.com]
12
+
13
+ spec.summary = "LIT object API"
14
+ spec.description = "LIT object generator and validator"
15
+ # spec.homepage = 'TODO'
16
+ spec.license = "MIT"
17
+
18
+ # spec.metadata['homepage_uri'] = spec.homepage
19
+ # spec.metadata['source_code_uri'] = 'TODO'
20
+
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = %w[lib]
28
+
29
+ spec.add_dependency "litl-parser", "0.1.0"
30
+
31
+ spec.add_development_dependency "bundler", "~> 2.1"
32
+ spec.add_development_dependency "rake", "~> 13.0"
33
+ spec.add_development_dependency "rspec", "~> 3.9"
34
+ spec.add_development_dependency "armitage-rubocop", "~> 0.79"
35
+ spec.add_development_dependency "rubocop-config-umbrellio", "~> 0.79"
36
+ spec.add_development_dependency "simplecov", "~> 0.17"
37
+ spec.add_development_dependency "pry", "~> 0.12"
38
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: litl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexander
8
+ - Komarov
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2020-07-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: litl-parser
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '='
19
+ - !ruby/object:Gem::Version
20
+ version: 0.1.0
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '='
26
+ - !ruby/object:Gem::Version
27
+ version: 0.1.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '2.1'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '2.1'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '13.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '13.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '3.9'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '3.9'
70
+ - !ruby/object:Gem::Dependency
71
+ name: armitage-rubocop
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.79'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.79'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop-config-umbrellio
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.79'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.79'
98
+ - !ruby/object:Gem::Dependency
99
+ name: simplecov
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.17'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.17'
112
+ - !ruby/object:Gem::Dependency
113
+ name: pry
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '0.12'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '0.12'
126
+ description: LIT object generator and validator
127
+ email:
128
+ - ak@akxcv.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".rspec"
135
+ - ".rubocop.yml"
136
+ - ".ruby-version"
137
+ - ".travis.yml"
138
+ - Gemfile
139
+ - Gemfile.lock
140
+ - LICENSE.txt
141
+ - Rakefile
142
+ - bin/console
143
+ - lib/lit.rb
144
+ - lib/lit/builder.rb
145
+ - lib/lit/builder/array.rb
146
+ - lib/lit/builder/map.rb
147
+ - lib/lit/builder/object.rb
148
+ - lib/lit/builder/option.rb
149
+ - lib/lit/errors.rb
150
+ - lib/lit/loader.rb
151
+ - lib/lit/module_observer.rb
152
+ - lib/lit/object.rb
153
+ - lib/lit/object/array.rb
154
+ - lib/lit/object/enum.rb
155
+ - lib/lit/object/enum_variant.rb
156
+ - lib/lit/object/map.rb
157
+ - lib/lit/object/option.rb
158
+ - lib/lit/object/struct.rb
159
+ - lib/lit/request_deserializer.rb
160
+ - lib/lit/serializer.rb
161
+ - lib/lit/type_checker.rb
162
+ - lib/lit/utils.rb
163
+ - lib/lit/version.rb
164
+ - litl.gemspec
165
+ homepage:
166
+ licenses:
167
+ - MIT
168
+ metadata: {}
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: 2.5.0
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubyforge_project:
185
+ rubygems_version: 2.7.6.2
186
+ signing_key:
187
+ specification_version: 4
188
+ summary: LIT object API
189
+ test_files: []