property_string 0.0.1 → 0.0.2

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +21 -8
  3. data/lib/property_string.rb +24 -3
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1599cc1dcb3a805c49f5d128df2d3c0a2a1d6de8d8f1348dba0e75a39d28827a
4
- data.tar.gz: 4d62dcd17afbb2463114cb26a676b56ac25ea3f8da4adfdda0fadcdc5b7d48fb
3
+ metadata.gz: 51ee8a1498b474f470fe167dd6e522edc6027fd09bfa036322c9ac6cd3de233c
4
+ data.tar.gz: 6ab9cd09fa918b1fd2b383c52e04b41f9677db59beee66081077d45040834637
5
5
  SHA512:
6
- metadata.gz: 06d7eb0788c96fcd4a63d06f423b17568c1237f7070ffa19834cf4cde5036824d01da0cf5205dde497fb3e7f4bb5c75bd79bb5a92eb1cfadecbe69db32de82da
7
- data.tar.gz: ab9f57a4adc63d312fc1acd376617e35ff170732174277ce85624a8563757202d600670a684cffe35d71e785500b662b9230135bfd71c4e89c0ab194080fa646
6
+ metadata.gz: 1993da29de7e214db0be4de670f298e2effe63be7ecb610b5f7d8aa3dcf97ec3a3b639cfac54a65be50bda16dfbdb7705fb6d22af5df93974381c021cd5ecdb3
7
+ data.tar.gz: 9f8ca4eb9d4fcc5765dc29c53f6ac7f10064c9fe5d5d9f7b782d19b8a4f5da856d8940fc2e492dcc53a61d2d8b61e2889da8367d8c11850c679f00bd8d9d3c09
data/README.md CHANGED
@@ -36,24 +36,37 @@ ps["company.does_not_exist!"] # NoMethodError
36
36
  # Can work with a Hash
37
37
  h.dig(:some, "nested", :hash) # foo
38
38
 
39
- ph = PropertyString(h)
40
- ph["some.nested.hash"]
39
+ ps = PropertyString(h)
40
+ ps["some.nested.hash"]
41
41
 
42
42
  # Or an Array
43
43
  a[0][0][0]
44
44
 
45
- ph = PropertyString(a)
46
- ph["0.0.0"]
45
+ ps = PropertyString(a)
46
+ ps["0.0.0"]
47
47
 
48
- # Ignore MethodMissing errors for unknown properties
48
+ # Fetching
49
+ ps.fetch("posts.9999", "your default")
50
+ ps.fetch("posts.9999") { |key| "some_default_for_#{key}" }
51
+ ```
52
+
53
+ ### Ignore `NoMethodError` for Unknown Properties
54
+
55
+ ```rb
49
56
  ps = PropertyString.new(product, :raise_if_method_missing => false)
50
57
  ps["company.does_not_exist!"] # nil
58
+ ```
51
59
 
52
- # Fetching
53
- ps.fetch("posts.9999", "your default") # shaw
54
- ps.fetch("posts.9999") { |key| "some_default_for_#{key}" }
60
+ ### Restrict Methods That Can Be Called
61
+
62
+ ```rb
63
+ ps = PropertyString.new(product, :whitelist => { Product => %w[company], Company => %w[name] })
64
+ ps["id"] # PropertyString::MethodNotAllowed
65
+ ps["company.id"] # PropertyString::MethodNotAllowed
55
66
  ```
56
67
 
68
+ Currently does not work when a superclass is whitelisted but trivial to add.
69
+
57
70
  ## See Also
58
71
 
59
72
  - [PropertyHash](https://github.com/sshaw/property_hash) - Access a nested Ruby Hash using Java-style properties as keys.
@@ -1,14 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class PropertyString
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  KEY_NOT_FOUND = "__#{object_id}-not-found-placeholder-#{object_id}__"
6
6
 
7
+ class MethodNotAllowed < StandardError
8
+ def initialize(object, method)
9
+ target = object.is_a?(Class) ? "#{object}.#{method}" : "#{object.class}##{method}"
10
+ super "Access to #{target} is not allowed"
11
+ end
12
+ end
13
+
7
14
  def initialize(object, options = nil)
8
15
  @object = object
9
16
 
10
17
  @options = (options || {}).dup
11
18
  @options[:raise_if_method_missing] = true unless @options.include?(:raise_if_method_missing)
19
+ @options[:whitelist] = @options[:whitelist] || {}
12
20
  end
13
21
 
14
22
  def [](property)
@@ -57,8 +65,12 @@ class PropertyString
57
65
  def find_non_index_value(value, prop)
58
66
  if value.is_a?(Hash)
59
67
  value = find_hash_value(value, prop)
60
- value == KEY_NOT_FOUND ? nil : value
61
- elsif @options[:raise_if_method_missing]
68
+ return value == KEY_NOT_FOUND ? nil : value
69
+ end
70
+
71
+ raise_if_method_not_allowed(value, prop)
72
+
73
+ if @options[:raise_if_method_missing]
62
74
  value.public_send(prop)
63
75
  elsif value.respond_to?(prop)
64
76
  value.public_send(prop)
@@ -94,4 +106,13 @@ class PropertyString
94
106
 
95
107
  KEY_NOT_FOUND
96
108
  end
109
+
110
+ def raise_if_method_not_allowed(value, prop)
111
+ klass = value.is_a?(Class) ? value : value.class
112
+ # Make sure we do not raise this if the object does not respond_to? prop
113
+ # TODO: class hierarchy
114
+ if @options[:whitelist].include?(klass) && !@options[:whitelist][klass].include?(prop) && value.respond_to?(prop)
115
+ raise MethodNotAllowed.new(value, prop)
116
+ end
117
+ end
97
118
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: property_string
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - sshaw
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-04 00:00:00.000000000 Z
11
+ date: 2024-05-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler