omg-attrs 0.1.0 → 0.1.1

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: f3eaed4c8a55dca3f9d6e4c6ecd00781116986cc1c81d1105960225bbfb74a85
4
- data.tar.gz: 65c6269712e3e992694866d0c95a96b8d27b3542e78807c7a842cc1bcc4fbc25
3
+ metadata.gz: 46eb3e016278c743e4eef8261a80305e04df785d995a3296ddabc657abd7d1c0
4
+ data.tar.gz: 4ea3a9f88a0b4d606a81bdfa8b1a8834f95af409be473f570388cd202dc2805f
5
5
  SHA512:
6
- metadata.gz: 4c5c5c1d6c2b3fa0604cb1c930f87b3953b62c3679066deca0818e132187cc37579037886f8ff0d1e0daaf4c426d7a0c68de0da2997b4380b41cc7d209754fa2
7
- data.tar.gz: 04c77582e0256724d3ed1dfa090dd398a3b5da7e5c5e0b450b94bf388532ca076fa7f3a03dbf51ddf0e04201e81b9268284a88e6970105d6785ccff4a61b2ea5
6
+ metadata.gz: 521c7d6cf9f04759159669879341e6de02aa9996e05c52492dfeed32d14efb02f896eeb82ab80f6ac67a8fe6672656bad57f265f1d0058ac003b7a4a0cc73be5
7
+ data.tar.gz: 838d9945288f976fd547b7f817672dc391c95875c60d0743bb6022ebaf78c6fe49aa71de33eba721dd2e532d80199cae750a0177e3cc4c26244e7758854e3839
data/lib/attrs.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pry-byebug'
4
+
3
5
  module Attrs
4
6
  def self.included(base)
5
7
  base.include(InstanceMethods)
@@ -7,8 +9,8 @@ module Attrs
7
9
 
8
10
  module InstanceMethods
9
11
  def attrs(*attrs)
10
- return map { |i| i.attrs(*attrs) } if is_list?(self)
11
-
12
+ return list_attrs(attrs) if is_list?
13
+
12
14
  base_attrs, nested_attrs = attrs.partition { |attr| attr.is_a?(Symbol) }
13
15
  nested_attrs.map! do |attr|
14
16
  if attr.is_a?(Hash)
@@ -21,25 +23,42 @@ module Attrs
21
23
  raise ArgumentError, "Invalid attribute: #{attr}"
22
24
  end
23
25
  end
24
-
25
- base_attrs = base_attrs.to_h { |attr| [attr, get(attr)] }
26
+
27
+ base_attrs = base_attrs.to_h do |attr|
28
+ [attr, get(attr)]
29
+ end
26
30
  nested_attrs.reduce(base_attrs, :merge)
27
31
  end
28
32
 
29
33
  private
30
34
 
31
- def nested_attrs(attr)
32
- attr.to_h do |key, value|
33
- records = get(key)
35
+ ##
36
+ # Returns a hash containing attributes on the list and attributes on individual items.
37
+ # @param attrs [Array]
38
+ # @return [Hash]
39
+ def list_attrs(attrs)
40
+ list, nested = attrs.partition { |attr| attr.is_a?(Symbol) && respond_to?(attr) }
41
+ list_attrs = list.empty? ? {} : list.to_h { |key| [key, get(key)] }
42
+ nested_attrs = nested.empty? ? {} : { items: map { |i| i.attrs(*nested) } }
34
43
 
35
- values = is_list?(records) ?
36
- records.map { |record| record.attrs(*value) } :
37
- records.attrs(*value)
44
+ list_attrs.merge(nested_attrs)
45
+ end
38
46
 
39
- [key, values]
47
+ ##
48
+ # Recursively retrieves nested attributes.
49
+ #
50
+ # @param attr [Array | Hash]
51
+ def nested_attrs(attr)
52
+ attr.to_h do |key, value|
53
+ [key, get(key).attrs(*value)]
40
54
  end
41
55
  end
42
56
 
57
+ ##
58
+ # Gets a single attribute for any object. If the object is a hash, it will return the value for the key.
59
+ #
60
+ # @param key [Symbol]
61
+ # @return [Object]
43
62
  def get(key)
44
63
  if respond_to?(key)
45
64
  send(key)
@@ -51,8 +70,11 @@ module Attrs
51
70
  end
52
71
  end
53
72
 
54
- def is_list?(object)
55
- object.is_a?(Enumerable) && !object.is_a?(Hash)
73
+ ##
74
+ # Hacky way of determining if a non-hash object is a list but is not
75
+ # technically an Array or Enumerable (e.g. ActiveRecord::Relation)
76
+ def is_list?
77
+ respond_to?(:each) && !is_a?(Hash)
56
78
  end
57
79
  end
58
80
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omg-attrs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Greenfield
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-30 00:00:00.000000000 Z
11
+ date: 2024-08-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Makes it easy to slice and dice objects and collections of objects
14
14
  email:
@@ -17,18 +17,12 @@ executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - ".rspec"
21
- - ".rubocop.yml"
22
- - README.md
23
- - attrs.gemspec
24
20
  - lib/attrs.rb
25
- - spec/attrs_spec.rb
26
- - spec/spec_helper.rb
27
- homepage: https://github.com/omgreenfield/omg-util/tree/main/attrs
21
+ homepage: https://github.com/omgreenfield/attrs
28
22
  licenses:
29
23
  - MIT
30
24
  metadata:
31
- homepage_uri: https://github.com/omgreenfield/omg-util/tree/main/attrs
25
+ homepage_uri: https://github.com/omgreenfield/attrs
32
26
  rubygems_mfa_required: 'true'
33
27
  post_install_message:
34
28
  rdoc_options: []
@@ -45,7 +39,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
45
39
  - !ruby/object:Gem::Version
46
40
  version: '0'
47
41
  requirements: []
48
- rubygems_version: 3.5.9
42
+ rubygems_version: 3.5.17
49
43
  signing_key:
50
44
  specification_version: 4
51
45
  summary: Allows all objects to call `.attrs` which acts as a recursive `.slice` method
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,13 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 2.7.8
3
-
4
- Style/StringLiterals:
5
- Enabled: true
6
- EnforcedStyle: single_quotes
7
-
8
- Style/StringLiteralsInInterpolation:
9
- Enabled: true
10
- EnforcedStyle: single_quotes
11
-
12
- Layout/LineLength:
13
- Max: 120
data/README.md DELETED
@@ -1,45 +0,0 @@
1
- # Attrs
2
-
3
- ## Installation
4
-
5
- ### Testing locally
6
- ```sh
7
- # Build gem
8
- gem build attrs.gemspec
9
-
10
- # Install gem
11
- gem i -l /path/to/this/folder/omg-attrs-0.1.0.gem
12
- ```
13
-
14
- ## Usage
15
-
16
- ```ruby
17
- dad_hash = {
18
- age: 35,
19
- hair_color: 'brown',
20
- children: [
21
- { age: 7, hair_color: 'blonde' },
22
- { age: 3, hair_color: 'brown' }
23
- ],
24
- wife: { age: 35, hair_color: 'brown' }
25
- }
26
-
27
- dad_hash.attrs(:age) # => 35
28
- dad_hash.attrs(wife: :age, children: :hair_color) # =>
29
- # {
30
- # wife: 35,
31
- # children: [
32
- # { hair_color: 'blonde' },
33
- # { hair_color: 'brown' },
34
- # ],
35
- # }
36
- ```
37
-
38
- ## Running tests
39
-
40
- ```ruby
41
- rspec
42
-
43
- # or
44
- bundle exec rspec
45
- ```
data/attrs.gemspec DELETED
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Gem::Specification.new do |spec|
4
- spec.name = 'omg-attrs'
5
- spec.version = '0.1.0'
6
- spec.authors = ['Matthew Greenfield']
7
- spec.email = ['mattgreenfield1@gmail.com']
8
-
9
- spec.summary = 'Allows all objects to call `.attrs` which acts as a recursive `.slice` method'
10
- spec.description = 'Makes it easy to slice and dice objects and collections of objects'
11
-
12
- spec.homepage = 'https://github.com/omgreenfield/omg-util/tree/main/attrs'
13
- spec.license = 'MIT'
14
- spec.required_ruby_version = '>= 2.7.0'
15
-
16
- spec.metadata['homepage_uri'] = spec.homepage
17
- spec.metadata['rubygems_mfa_required'] = 'true'
18
-
19
- spec.files = Dir.chdir(__dir__) do
20
- `git ls-files -z`.split("\x0").reject do |f|
21
- (File.expand_path(f) == __FILE__) ||
22
- f.start_with?(*%w[spec/.git .github Gemfile])
23
- end
24
- end
25
- spec.require_paths = ['lib']
26
- end
data/spec/attrs_spec.rb DELETED
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'ostruct'
4
-
5
- RSpec.describe Attrs do
6
- it 'allows recursive slice-like attribute fetching' do
7
- dad_hash = {
8
- age: 35,
9
- hair_color: 'brown',
10
- children: [
11
- { age: 7, hair_color: 'blonde' },
12
- { age: 3, hair_color: 'brown' }
13
- ],
14
- wife: { age: 35, hair_color: 'brown' }
15
- }
16
-
17
- expect(dad_hash.attrs(:age, wife: %i[hair_color age], children: %i[hair_color age])).to eq(
18
- {
19
- age: 35,
20
- wife: { hair_color: 'brown', age: 35 },
21
- children: [
22
- { hair_color: 'blonde', age: 7 },
23
- { hair_color: 'brown', age: 3 },
24
- ],
25
- }
26
- )
27
-
28
- dad_object = OpenStruct.new(dad_hash)
29
- expect(dad_object.attrs(:age, wife: %i[hair_color age], children: %i[hair_color age])).to eq(
30
- {
31
- age: 35,
32
- wife: { hair_color: 'brown', age: 35 },
33
- children: [
34
- { hair_color: 'blonde', age: 7 },
35
- { hair_color: 'brown', age: 3 },
36
- ],
37
- }
38
- )
39
-
40
- children_array = dad_object.children
41
- expect(children_array.attrs(:hair_color, :age)).to eq([{ hair_color: 'blonde', age: 7 }, { hair_color: 'brown', age: 3 }])
42
- end
43
- end
data/spec/spec_helper.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "attrs"
4
-
5
- RSpec.configure do |config|
6
- # Enable flags like --only-failures and --next-failure
7
- config.example_status_persistence_file_path = ".rspec_status"
8
-
9
- # Disable RSpec exposing methods globally on `Module` and `main`
10
- config.disable_monkey_patching!
11
-
12
- config.expect_with :rspec do |c|
13
- c.syntax = :expect
14
- end
15
- end