attributor 6.2 → 6.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82e7c7fa061464ff15336123c9809e743e2111da05c7155b2e20f6ece94196e3
4
- data.tar.gz: 0cfdbaf2baa22792c3ccbaceffed7950131d9e2b4a7d67d5723e080e40e13873
3
+ metadata.gz: b30fd80bf80e1fba073207107cc6ee008d8f7f5edc3acd49863d58d27c9b2caa
4
+ data.tar.gz: 7549362dfe5fb7f1eb654ab7927996baee065f4b37cbdb74fcfb472189b8ea17
5
5
  SHA512:
6
- metadata.gz: ccc3cc9e5ca7ae70b69501831559e616e5a631b7fe6b67b59c099399d7f1ee53479f657c5d951e0f20b84eb12e0a19643f8a83060e50684925652c25b5ec4527
7
- data.tar.gz: e01d93ff03633e0a3361236fa2a76aa450880bd2f0594cbc2348da0daf9ecc7ec1c821d69fd4c020609a53e1ec4cac9886d84e9b4864c4def46f6a0c02174e69
6
+ metadata.gz: 46fb615c0952564d354ed67e9ed4e794bead86868111cf3a1447f1aab92e9a8106addca135673b59acb67f58dfdbbc5ed8a49d9f5f5cebdf5a2439719c495768
7
+ data.tar.gz: 726a29e1f6a30025f51a62dfb63fc8331e3202a3553f031ad776679ee7a525a7e689feb75ed184d0eb306b6bbe6b7c03605bb6b396fd5e234e0ddc1fa751b2e8
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## next
4
4
 
5
+ ## 6.3 (10/21/2022)
6
+ - Added some small utility enhancements for dealing with attributes and types
7
+ * .duplicate an attribute, with a different inner type and/or options
8
+ * .slice a Hash/Model/Struct to reduce the number of keys that it holds
9
+ * .merge two Hash/Model/Struct keys into an existing one (even if the types differ)
10
+
5
11
  ## 6.2 (5/11/2022)
6
12
  - Added .to_hash for Model/Struct, which returns a symbolized key hash (without recursing). This allows to splat instances of Model/Structs into functions that have keyword arguments.
7
13
 
@@ -45,6 +45,13 @@ module Attributor
45
45
  check_options!
46
46
  end
47
47
 
48
+ def duplicate(type: nil, options: nil)
49
+ clone.tap do |cloned|
50
+ cloned.instance_variable_set(:@type, type) if type
51
+ cloned.instance_variable_set(:@options, options) if options
52
+ end
53
+ end
54
+
48
55
  def ==(other)
49
56
  raise ArgumentError, "can not compare Attribute with #{other.class.name}" unless other.is_a?(Attribute)
50
57
 
@@ -41,6 +41,13 @@ module Attributor
41
41
  @error = false
42
42
  @requirements = []
43
43
 
44
+ def self.slice!(*keys)
45
+ missing_keys = keys - @keys.keys
46
+ raise AttributorException, "Cannot slice! this type, because it does not contain one or more of the requested keys: #{missing_keys}" unless missing_keys.empty?
47
+ instance_variable_set(:@keys, @keys.slice(*keys))
48
+ self
49
+ end
50
+
44
51
  def self.key_type=(key_type)
45
52
  @key_type = Attributor.resolve_type(key_type)
46
53
  @key_attribute = Attribute.new(@key_type)
@@ -461,6 +468,7 @@ module Attributor
461
468
  else
462
469
  hash[:value] = { type: value_type.describe(true) }
463
470
  hash[:example] = example if example
471
+ hash[:attributes] = {}
464
472
  end
465
473
 
466
474
  hash
@@ -567,7 +575,15 @@ module Attributor
567
575
  when self.class
568
576
  self.class.new(contents.merge(h.contents))
569
577
  when Attributor::Hash
570
- raise ArgumentError, 'cannot merge Attributor::Hash instances of different types' unless h.is_a?(self.class)
578
+ source_key_type = self.class.key_type
579
+ source_value_type = self.class.value_type
580
+ # Allow merging hashes, but we'll need to coerce keys and/or values if they aren't the same type
581
+ coerced_contents = h.contents.each_with_object({}) do |(key, val), object|
582
+ k = (source_key_type && !k.is_a?(source_key_type)) ? source_key_type.load(key) : key
583
+ v = (source_value_type && !k.is_a?(source_value_type)) ? source_value_type.load(val) : val
584
+ object[k] = v
585
+ end
586
+ self.class.new(contents.merge(coerced_contents))
571
587
  else
572
588
  raise TypeError, "no implicit conversion of #{h.class} into Attributor::Hash"
573
589
  end
@@ -1,3 +1,3 @@
1
1
  module Attributor
2
- VERSION = '6.2'.freeze
2
+ VERSION = '6.3'.freeze
3
3
  end
@@ -1189,16 +1189,15 @@ describe Attributor::Hash do
1189
1189
  end
1190
1190
 
1191
1191
  context '#merge' do
1192
- let(:hash_of_strings) { Attributor::Hash.of(key: String) }
1193
- let(:hash_of_symbols) { Attributor::Hash.of(key: Symbol) }
1192
+ let(:hash_of_strings) { Attributor::Hash.of(key: String, value: Integer) }
1193
+ let(:hash_of_symbols_and_string_vals) { Attributor::Hash.of(key: Symbol) }
1194
1194
 
1195
1195
  let(:merger) { hash_of_strings.load({'a' => 1},nil) }
1196
1196
  let(:good_mergee) { hash_of_strings.load({'b' => 2},nil) }
1197
- let(:bad_mergee) { hash_of_symbols.load({c: 3}) }
1197
+ let(:different_hash_mergee) { hash_of_symbols_and_string_vals.load({c: '3'}) }
1198
1198
  let(:result) { hash_of_strings.load({'a' => 1, 'b' => 2},nil) }
1199
1199
 
1200
1200
  it 'validates that the mergee is of like type' do
1201
- expect { merger.merge(bad_mergee) }.to raise_error(ArgumentError)
1202
1201
  expect { merger.merge({}) }.to raise_error(TypeError)
1203
1202
  expect { merger.merge(nil) }.to raise_error(TypeError)
1204
1203
  end
@@ -1210,6 +1209,14 @@ describe Attributor::Hash do
1210
1209
  it 'merges' do
1211
1210
  expect(merger.merge(good_mergee)).to eq(result)
1212
1211
  end
1212
+
1213
+ it 'allows Hash merges, even if they come from different types, by coercing keys/values' do
1214
+ merged = merger.merge(different_hash_mergee)
1215
+ expect(merged).to be_a(hash_of_strings)
1216
+ result = hash_of_strings.load({'a' => 1, 'c' => 3},nil)
1217
+ # :c is coerced to 'c' and values are coerced to integers
1218
+ expect(merged).to eq(result)
1219
+ end
1213
1220
  end
1214
1221
 
1215
1222
  context Attributor::InvalidDefinition do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attributor
3
3
  version: !ruby/object:Gem::Version
4
- version: '6.2'
4
+ version: '6.3'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josep M. Blanquer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-05-11 00:00:00.000000000 Z
12
+ date: 2022-10-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: hashie