property_string 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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