low_type 0.8.7 → 0.8.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94ec8cf1ae80a7540248e9a0a97e2e9bbc99fb81724f9a89e3d35de0ccd3dfaa
4
- data.tar.gz: f1bf339671b5d17ec247814a08ea665aca64df51f404f625dff5d6bf77cf7c2e
3
+ metadata.gz: b542b5e282a1c49db5ff50843ca16eae7ad0a6f50c143dd2568b4eed77b951ce
4
+ data.tar.gz: deeb4c06c3e78041eefd69ddb0ab16c5317c2b4ec28306092cbd0a608d6b862b
5
5
  SHA512:
6
- metadata.gz: 7a6ff0fa4038f53cd1650f27e7523ec2e0c0ac75c66190d62d976dbaded7887c2dc1900cb514709255af87f1c01545eb7c0748c100cd8133ea947c3d03f0c785
7
- data.tar.gz: 141e666816a66e0446b0d9559d288dc24b7e838c200537fbfd5b18297533f8812517e37e29d3bcf7388efbef82fffb1aa90a6407037c4803db8bc6a1b26645f8
6
+ metadata.gz: 7518519f80e3ba2edc2cd114a6fef9676e3866ac6c5032f983867cd8ab70a62de7e20113ed076c223e027c517654bd3538187eebd88a11964f46d8bdced623f0
7
+ data.tar.gz: d6fee3d4fd5a7135e91eeafe090ed844fbde9bfb5b495e1022352910544f76d0c5074d2c7cb04657d18d421b50977b0194cd7a6f546bb4dbec37c8483023c849
@@ -1,8 +1,8 @@
1
1
  require 'prism'
2
2
 
3
- require_relative 'sinatra_return_proxy'
4
3
  require_relative '../interfaces/adapter_interface'
5
4
  require_relative '../proxies/file_proxy'
5
+ require_relative '../proxies/return_proxy'
6
6
  require_relative '../error_types'
7
7
 
8
8
  module LowType
@@ -17,7 +17,7 @@ module LowType
17
17
  @file_path = file_path
18
18
  end
19
19
 
20
- def redefine_methods
20
+ def process
21
21
  method_calls = @parser.method_calls(method_names: [:get, :post, :patch, :put, :delete, :options, :query])
22
22
 
23
23
  # Type check return values.
@@ -35,54 +35,35 @@ module LowType
35
35
 
36
36
  route = "#{method_call.name.upcase} #{pattern}"
37
37
  @klass.low_methods[route] = MethodProxy.new(name: method_call.name, params:, return_proxy:)
38
+ end
39
+ end
38
40
 
39
- # We're in Sinatra now. Objects request/response are from Sinatra.
40
- @klass.after pattern do
41
- if (method_proxy = self.class.low_methods["#{request.request_method} #{pattern}"])
42
- proxy = method_proxy.return_proxy
41
+ def redefine
42
+ Module.new do
43
+ def invoke(&block)
44
+ res = catch(:halt, &block)
43
45
 
44
- # Inclusive rather than exclusive validation. If one type/value is valid then there's no need to error.
45
- valid_type = proxy.type_expression.types.any? do |type|
46
- proxy.type_expression.validate(value: SinatraAdapter.reconstruct_return_value(type:, response:), proxy:)
47
- end
46
+ raise AllowedTypeError, 'Did you mean "Response.finish"?' if res.to_s == 'Response'
48
47
 
49
- # No valid types so let's return a server error to the client.
50
- unless valid_type
51
- proxy.type_expression.types.each do |type|
52
- value = SinatraAdapter.reconstruct_return_value(type:, response:)
53
- unless proxy.type_expression.validate(value:, proxy:)
54
- halt 500, {}, proxy.error_message(value: value.inspect)
55
- end
56
- end
48
+ route = "#{request.request_method} #{request.path}"
49
+ if (res && (method_proxy = self.class.low_methods[route]) && (proxy = method_proxy.return_proxy))
50
+ proxy.type_expression.types.each do |type|
51
+ proxy.type_expression.validate!(value: res, proxy:)
57
52
  end
58
53
  end
59
- end
60
- end
61
- end
62
54
 
63
- # The route's String/Array/Enumerable return value populates a Rack::Response object.
64
- # This response also contains values added via Sinatra DSL's header()/body() methods.
65
- # So reconstruct the return value from the response object, based on the return type.
66
- def self.reconstruct_return_value(type:, response:)
67
- valid_types = {
68
- Integer => -> (response) { response.status },
69
- String => -> (response) { response.body.first },
70
- HTML => -> (response) { response.body.first },
71
- JSON => -> (response) { response.body.first },
72
-
73
- [String] => -> (response) { response.body }, # Body is stored internally as an array.
74
- [Integer, String] => -> (response) { [response.status, response.body.first] },
75
- [Integer, Hash, String] => -> (response) { [response.status, response.headers, response.body.first] },
76
-
77
- # TODO: Represent Enumerable[T]. How would we match a Module of a class in a hash key?
78
- }
79
-
80
- raise AllowedTypeError, 'Did you mean "Response.finish"?' if type.to_s == 'Response'
81
-
82
- if (reconstructed_value = valid_types[type])
83
- return reconstructed_value.call(response)
84
- else
85
- raise AllowedTypeError, "Valid Sinatra return types: #{valid_types.keys.map(&:to_s).join(' | ')}"
55
+ res = [res] if (Integer === res) || (String === res)
56
+ if (Array === res) && (Integer === res.first)
57
+ res = res.dup
58
+ status(res.shift)
59
+ body(res.pop)
60
+ headers(*res)
61
+ elsif res.respond_to? :each
62
+ body res
63
+ end
64
+
65
+ nil # avoid double setting the same response tuple twice
66
+ end
86
67
  end
87
68
  end
88
69
 
@@ -95,7 +76,7 @@ module LowType
95
76
  expression = eval(return_type.slice).call
96
77
  expression = TypeExpression.new(type: expression) unless TypeExpression === expression
97
78
 
98
- SinatraReturnProxy.new(type_expression: expression, name: "#{method_node.name.upcase} #{pattern}", file:)
79
+ ReturnProxy.new(type_expression: expression, name: "#{method_node.name.upcase} #{pattern}", file:)
99
80
  end
100
81
  end
101
82
  end
data/lib/basic_types.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module LowType
2
2
  class Boolean; end # TrueClass or FalseClass
3
+
3
4
  class HTML < String; end
4
5
  class JSON < String; end
6
+ class XML < String; end
5
7
  end
@@ -1,6 +1,6 @@
1
1
  module LowType
2
2
  class AdapterInterface
3
- def redefine_methods
3
+ def process
4
4
  raise NotImplementedError
5
5
  end
6
6
  end
data/lib/low_type.rb CHANGED
@@ -43,8 +43,10 @@ module LowType
43
43
  klass.prepend LowType::Redefiner.redefine_methods(method_nodes: parser.instance_methods, klass:, private_start_line:, file_path:)
44
44
  klass.singleton_class.prepend LowType::Redefiner.redefine_methods(method_nodes: parser.class_methods, klass:, private_start_line:, file_path:)
45
45
 
46
- adapter = AdapterLoader.load(klass:, parser:, file_path:)
47
- adapter.redefine_methods if adapter
46
+ if (adapter = AdapterLoader.load(klass:, parser:, file_path:))
47
+ adapter.process
48
+ klass.prepend adapter.redefine
49
+ end
48
50
  ensure
49
51
  Array.define_singleton_method('[]', array_class_method)
50
52
  Hash.define_singleton_method('[]', hash_class_method)
@@ -84,7 +84,7 @@ module LowType
84
84
  # [T, T, T]
85
85
  if types.length > 1
86
86
  types.each_with_index do |type, index|
87
- return false unless type === values[index]
87
+ return false unless type <= values[index].class # Example: HTML is a subclass of String and should pass as a String.
88
88
  end
89
89
  # [T]
90
90
  elsif types.length == 1
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LowType
4
- VERSION = '0.8.7'
4
+ VERSION = '0.8.8'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: low_type
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - maedi
@@ -19,7 +19,6 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - lib/adapters/adapter_loader.rb
21
21
  - lib/adapters/sinatra_adapter.rb
22
- - lib/adapters/sinatra_return_proxy.rb
23
22
  - lib/basic_types.rb
24
23
  - lib/error_types.rb
25
24
  - lib/interfaces/adapter_interface.rb
@@ -1,18 +0,0 @@
1
- require_relative '../proxies/return_proxy'
2
-
3
- module LowType
4
- class SinatraReturnProxy < ReturnProxy
5
- attr_reader :type_expression, :name
6
-
7
- def initialize(type_expression:, name:, file:)
8
- @type_expression = type_expression
9
- @name = name
10
- @file = file
11
- end
12
-
13
- def error_message(value:)
14
- value = value[0...20] if value
15
- "Invalid return value '#{value}' for method '#{@name}'. Valid types: '#{@type_expression.valid_types}'"
16
- end
17
- end
18
- end