structure 3.6.2 → 3.6.3

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: 49afeef61e56c6e3f65ad2eff0855af54552ee4dbcab2282a8d0194e30156362
4
- data.tar.gz: 1b7889d683dd5a129d35446773729212ea0f1348958688e4520f98fab8d90e8f
3
+ metadata.gz: 3ecf2906322a2c0abaa86ab756c7154139788867b214ee5b30a071adf5e044ff
4
+ data.tar.gz: c36c7b4dfc5656a74b056c72af11ab478fc97886a1638312dd389d252e1977b3
5
5
  SHA512:
6
- metadata.gz: 1c6ab2be186a6a1eec57cc1bdad3627cccbcd91c20ff803a69d789cd694568c128853431ccb14b7694980700ef95675555919e5e944bf5df54c13c11497c2a19
7
- data.tar.gz: 6d942ea5cc6bb8d012c8c7245480f7bb66857fb30ec20d8afd948183c7c29220baa9129abca1f17037c4db62c159e6860fe0a82c6c837639741c5c9ccec43c7a
6
+ metadata.gz: f6bcd31e925af5a25bb65b9ee1b2c4eff4654b7fbce6e7110d3c89195744b5ed7f3564a33dcf0b0cf19a373df315d955637388ccad8f6fa19aa394b21234e1d5
7
+ data.tar.gz: 3707eb84b1b0e702f4e13cf90b9048a3858ed71b07e399d969db4e4e36523fa4e9860c38fbe0d33a4b11336fb2b9f7389d136e80fa4ed280cd0301297102de56
data/lib/structure/rbs.rb CHANGED
@@ -66,7 +66,7 @@ module Structure
66
66
  lines << ""
67
67
 
68
68
  needs_parse_data = types.any? do |_attr, type|
69
- type == :self || type == [:self] || (type.is_a?(Array) && type.first == :array)
69
+ type == :self || type == [:self]
70
70
  end
71
71
 
72
72
  if needs_parse_data
@@ -111,13 +111,7 @@ module Structure
111
111
  when [:self]
112
112
  "Array[#{class_name} | parse_data]"
113
113
  when Array
114
- if type.first == :array && type.last == :self
115
- "Array[#{class_name} | parse_data]"
116
- elsif type.first == :array
117
- # For [:array, SomeType] format, use Array[untyped] since we coerce
118
- "Array[untyped]"
119
- elsif type.size == 1 && type.first == :self
120
- # [:self] is handled above, this shouldn't happen
114
+ if type.size == 1 && type.first == :self
121
115
  "Array[#{class_name} | parse_data]"
122
116
  elsif type.size == 1
123
117
  # Regular array type like [String], [Integer], etc.
@@ -136,16 +130,20 @@ module Structure
136
130
  def map_type_to_rbs(type, class_name)
137
131
  case type
138
132
  when Class
139
- type.name || "untyped"
133
+ if type == Array
134
+ "Array[untyped]"
135
+ elsif type == Hash
136
+ "Hash[untyped, untyped]"
137
+ else
138
+ type.name || "untyped"
139
+ end
140
+
140
141
  when :boolean
141
142
  "bool"
142
143
  when :self
143
144
  class_name || "untyped"
144
145
  when Array
145
- if type.size == 2 && type.first == :array
146
- element_type = map_type_to_rbs(type.last, class_name)
147
- "Array[#{element_type}]"
148
- elsif type.size == 1
146
+ if type.size == 1
149
147
  # Single element array means array of that type
150
148
  element_type = map_type_to_rbs(type.first, class_name)
151
149
  "Array[#{element_type}]"
@@ -36,20 +36,20 @@ module Structure
36
36
  self_referential
37
37
  when String
38
38
  string_class(type, context_class)
39
- when Array
40
- if type.length == 1
41
- array(type.first, context_class)
42
- else
43
- type
44
- end
39
+ when ->(t) { t.is_a?(Array) && t.length == 1 }
40
+ array(type.first, context_class)
41
+ when Hash
42
+ raise ArgumentError, "Cannot specify #{type.inspect} as type"
43
+ when ->(t) { t.respond_to?(:parse) }
44
+ parseable(type)
45
+ when ->(t) { t.respond_to?(:name) && t.name && Kernel.respond_to?(t.name) }
46
+ kernel(type)
47
+ when ->(t) { t.respond_to?(:call) }
48
+ type
49
+ when nil
50
+ type
45
51
  else
46
- if type.respond_to?(:parse)
47
- parseable(type)
48
- elsif type.respond_to?(:name) && type.name && Kernel.respond_to?(type.name)
49
- kernel(type)
50
- else
51
- type
52
- end
52
+ raise ArgumentError, "Cannot specify #{type.inspect} as type"
53
53
  end
54
54
  end
55
55
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Structure
4
- VERSION = "3.6.2"
4
+ VERSION = "3.6.3"
5
5
  end
data/lib/structure.rb CHANGED
@@ -65,59 +65,57 @@ module Structure
65
65
  h
66
66
  end
67
67
 
68
- # parse accepts JSON-ish hashes + kwargs override - using string eval to avoid closure capture
69
- klass.singleton_class.class_eval(<<~RUBY)
70
- def parse(data = {}, **kwargs)
71
- return data if data.is_a?(self)
68
+ # parse accepts JSON-ish hashes + kwargs override
69
+ klass.singleton_class.define_method(:parse) do |data = {}, **kwargs|
70
+ return data if data.is_a?(self)
72
71
 
73
- unless data.respond_to?(:merge!)
74
- raise TypeError, "can't convert \#{data.class} into \#{self}"
75
- end
76
-
77
- # @type var kwargs: Hash[Symbol, untyped]
78
- string_kwargs = kwargs.transform_keys(&:to_s)
79
- data.merge!(string_kwargs)
80
- # @type self: singleton(Data) & _StructuredDataClass
81
- # @type var final: Hash[Symbol, untyped]
82
- final = {}
83
-
84
- # @type var meta: untyped
85
- meta = __structure_meta__
72
+ unless data.respond_to?(:merge!)
73
+ raise TypeError, "can't convert #{data.class} into #{self}"
74
+ end
86
75
 
87
- attributes = meta.fetch(:attributes)
88
- defaults = meta.fetch(:defaults)
89
- mappings = meta.fetch(:mappings)
90
- coercions = meta.fetch(:coercions)
91
- after = meta.fetch(:after)
76
+ # @type var kwargs: Hash[Symbol, untyped]
77
+ string_kwargs = kwargs.transform_keys(&:to_s)
78
+ data.merge!(string_kwargs)
79
+ # @type self: singleton(Data) & _StructuredDataClass
80
+ # @type var final: Hash[Symbol, untyped]
81
+ final = {}
82
+
83
+ # @type var meta: untyped
84
+ meta = __structure_meta__
85
+
86
+ attributes = meta.fetch(:attributes)
87
+ defaults = meta.fetch(:defaults)
88
+ mappings = meta.fetch(:mappings)
89
+ coercions = meta.fetch(:coercions)
90
+ after = meta.fetch(:after)
91
+
92
+ attributes.each do |attr|
93
+ source = mappings[attr] || attr.to_s
94
+ value =
95
+ if data.key?(source) then data[source]
96
+ elsif data.key?(source.to_sym) then data[source.to_sym]
97
+ elsif defaults.key?(attr) then defaults[attr]
98
+ end
92
99
 
93
- attributes.each do |attr|
94
- source = mappings[attr] || attr.to_s
100
+ coercion = coercions[attr]
101
+ if coercion && !value.nil?
102
+ # Procs (not lambdas) need class context for self-referential parsing
103
+ # Lambdas and other callables use direct invocation
95
104
  value =
96
- if data.key?(source) then data[source]
97
- elsif data.key?(source.to_sym) then data[source.to_sym]
98
- elsif defaults.key?(attr) then defaults[attr]
105
+ if coercion.is_a?(Proc) && !coercion.lambda?
106
+ instance_exec(value, &coercion) # steep:ignore
107
+ else
108
+ coercion.call(value)
99
109
  end
100
-
101
- coercion = coercions[attr]
102
- if coercion && !value.nil?
103
- # Procs (not lambdas) need class context for self-referential parsing
104
- # Lambdas and other callables use direct invocation
105
- value =
106
- if coercion.is_a?(Proc) && !coercion.lambda?
107
- instance_exec(value, &coercion) # steep:ignore
108
- else
109
- coercion.call(value)
110
- end
111
- end
112
-
113
- final[attr] = value
114
110
  end
115
111
 
116
- obj = new(**final)
117
- after&.call(obj) if after
118
- obj
112
+ final[attr] = value
119
113
  end
120
- RUBY
114
+
115
+ obj = new(**final)
116
+ after&.call(obj)
117
+ obj
118
+ end
121
119
 
122
120
  klass
123
121
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: structure
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.2
4
+ version: 3.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hakan Ensari