hal_presenter 1.0.0 → 1.1.0

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: 2fe4271a7912587144464a955caafd6d5391f34b6f2ed3a41f5daa5249a39eeb
4
- data.tar.gz: c17ab721cbbd1ff37ae96fa921a3a3bb1d003f67943c13863058dfda60a42e4d
3
+ metadata.gz: e1cae2dc6aea584c397b91fc95c485b1e53602184c51d20760c02c7b0c76ac2f
4
+ data.tar.gz: 7e0abe48f0337d05bea36e1fe62e2c451d18450b6044f1a5200754cb387e98a3
5
5
  SHA512:
6
- metadata.gz: b0d7657cdb1609fe0a9e9a072be80ef61b9f9b8df31750575d9cbe007fdef6f86668b4a4c84431c1b94e04165195704eaced191443b8eaa7a3d91909f8b5bcc8
7
- data.tar.gz: 9dac165e3f659f3e36c7d1e3f3ec8af60cb74e93152f5f68361b1b13037157fac157d0b5a40e92a60425a2b6c686f2c46a47a43a5da001bbe3efb8d022a4de28
6
+ metadata.gz: a1f9cdfc3286ee107dd3600e7621bc1c1d435bc04c4a181301214d41999a3ea3a142522e692a85c925950cee4e4c6bb6df7449b26f53efd3a24be6ed54fcbac1
7
+ data.tar.gz: f157c99026624748d91be20cf8fcf99d294a29c11f9d93e90b3ff50419e65e928256698d74c4bb50bcba956ed8e071879b2930eaa1719254c43c808cc392d86d
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/lib/hal_presenter.rb CHANGED
@@ -9,6 +9,7 @@ require 'hal_presenter/serializer'
9
9
  require 'hal_presenter/deserializer'
10
10
  require 'hal_presenter/collection'
11
11
  require 'hal_presenter/serialize_hooks'
12
+ require 'hal_presenter/namespace'
12
13
 
13
14
  module HALPresenter
14
15
  include HALPresenter::Attributes
@@ -21,4 +22,5 @@ module HALPresenter
21
22
  include HALPresenter::Serializer
22
23
  include HALPresenter::Deserializer
23
24
  include HALPresenter::Policy
25
+ include HALPresenter::Namespace
24
26
  end
@@ -1,27 +1,22 @@
1
1
  require 'hal_presenter/property'
2
+ require 'hal_presenter/super_init'
2
3
 
3
4
  module HALPresenter
4
5
  module Attributes
5
- def attribute(*args, **kw_args, &block)
6
- @_attributes ||= __init_attributes
7
- @_attributes = @_attributes.reject { |attr| attr.name == args.first }
8
- @_attributes << Property.new(*args, **kw_args, &block)
6
+ include SuperInit
7
+
8
+ def attribute(*args, **kwargs, &block)
9
+ kwargs[:context] ||= self
10
+ attributes.delete_if { |attr| attr.name == args.first }
11
+ Property.new(*args, **kwargs, &block).tap do |attr|
12
+ attributes << attr
13
+ end
9
14
  end
10
15
 
11
16
  protected
12
17
 
13
18
  def attributes
14
- @_attributes ||= __init_attributes
15
- end
16
-
17
- private
18
-
19
- def __init_attributes
20
- return [] unless Class === self
21
- return [] unless superclass.respond_to?(:attributes, true)
22
- superclass.attributes.each do |attr|
23
- attr.change_context(self)
24
- end
19
+ @__attributes ||= __init_from_superclass(:attributes)
25
20
  end
26
21
  end
27
22
  end
@@ -1,7 +1,9 @@
1
1
  require 'hal_presenter/property'
2
+ require 'hal_presenter/super_init'
2
3
 
3
4
  module HALPresenter
4
5
  module Collection
6
+ include SuperInit
5
7
 
6
8
  class Properties
7
9
  include Attributes
@@ -18,6 +20,33 @@ module HALPresenter
18
20
  instance_exec(&block)
19
21
  end
20
22
 
23
+ def attribute(*args, **kwargs, &block)
24
+ kwargs[:context] = scope
25
+ super
26
+ end
27
+
28
+ def link(rel, value = nil, **kwargs, &block)
29
+ kwargs[:context] = scope
30
+ super
31
+ end
32
+
33
+ def curie(rel, value = nil, **kwargs, &block)
34
+ kwargs[:context] = scope
35
+ super
36
+ end
37
+
38
+ def embed(*args, **kwargs, &block)
39
+ kwargs[:context] = scope
40
+ super
41
+ end
42
+
43
+ def change_context(context)
44
+ @scope = context
45
+ self
46
+ end
47
+
48
+ private
49
+
21
50
  def method_missing(method, *args, &block)
22
51
  return super unless scope&.respond_to? method
23
52
  define_singleton_method(method) { |*a, &b| scope.public_send method, *a, &b }
@@ -31,26 +60,17 @@ module HALPresenter
31
60
  end
32
61
 
33
62
  def collection(of:, &block)
34
- @_collection_properties = Properties.new(of, self, &block)
63
+ @__collection_properties = Properties.new(of, self, &block)
35
64
  end
36
65
 
37
66
  protected
38
67
 
39
68
  def collection_properties
40
- @_collection_properties ||= __init_collection_params
69
+ @__collection_properties ||= __init_from_superclass(:collection_properties, default: nil)
41
70
  end
42
71
 
43
72
  def can_serialize_collection?
44
73
  !collection_properties.nil?
45
74
  end
46
-
47
- private
48
-
49
- def __init_collection_params
50
- return unless Class === self
51
- if superclass.respond_to?(:collection_properties, true)
52
- superclass.collection_properties
53
- end
54
- end
55
75
  end
56
76
  end
@@ -1,7 +1,10 @@
1
1
  require 'hal_presenter/property'
2
+ require 'hal_presenter/super_init'
2
3
 
3
4
  module HALPresenter
4
5
  module Curies
6
+ include SuperInit
7
+
5
8
  class Curie < HALPresenter::Property
6
9
  def to_h(resource = nil, options = {})
7
10
  href = value(resource, options)
@@ -15,29 +18,22 @@ module HALPresenter
15
18
  end
16
19
  end
17
20
 
18
- def curie(rel, value = nil, embed_depth: nil, &block)
21
+ def curie(rel, value = nil, **kwargs, &block)
19
22
  if value.nil? && !block_given?
20
23
  raise 'curie must be called with non nil value or be given a block'
21
24
  end
22
- @_curies ||= __init_curies
23
- @_curies = @_curies.reject { |curie| curie.name == rel }
24
- @_curies << Curie.new(rel, value, embed_depth: embed_depth, &block)
25
+
26
+ kwargs[:context] ||= self
27
+ curies.delete_if { |curie| curie.name == rel }
28
+ Curie.new(rel, value, **kwargs, &block).tap do |curie|
29
+ curies << curie
30
+ end
25
31
  end
26
32
 
27
33
  protected
28
34
 
29
35
  def curies
30
- @_curies ||= __init_curies
31
- end
32
-
33
- private
34
-
35
- def __init_curies
36
- return [] unless Class === self
37
- return [] unless superclass.respond_to?(:curies, true)
38
- superclass.curies.each do |curie|
39
- curie.change_context(self)
40
- end
36
+ @_curies ||= __init_from_superclass(:curies)
41
37
  end
42
38
  end
43
39
  end
@@ -1,36 +1,31 @@
1
1
  require 'hal_presenter/property'
2
+ require 'hal_presenter/super_init'
2
3
 
3
4
  module HALPresenter
4
5
  module Embedded
6
+ include SuperInit
7
+
5
8
  class Embed < HALPresenter::Property
6
9
  attr_reader :presenter_class
7
10
 
8
- def initialize(name, value = nil, **kw_args, &block)
9
- @presenter_class = kw_args.delete(:presenter_class)
10
- super(name, value, **kw_args, &block)
11
+ def initialize(name, value = nil, **kwargs, &block)
12
+ @presenter_class = kwargs.delete(:presenter_class)
13
+ super(name, value, **kwargs, &block)
11
14
  end
12
15
  end
13
16
 
14
- def embed(*args, **kw_args, &block)
15
- @_embedded ||= __init_embedded
16
- @_embedded = @_embedded.reject { |embed| embed.name == args.first }
17
- @_embedded << Embed.new(*args, **kw_args, &block)
17
+ def embed(*args, **kwargs, &block)
18
+ kwargs[:context] ||= self
19
+ embedded.delete_if { |embed| embed.name == args.first }
20
+ Embed.new(*args, **kwargs, &block).tap do |embed|
21
+ embedded << embed
22
+ end
18
23
  end
19
24
 
20
25
  protected
21
26
 
22
27
  def embedded
23
- @_embedded ||= __init_embedded
24
- end
25
-
26
- private
27
-
28
- def __init_embedded
29
- return [] unless Class === self
30
- return [] unless superclass.respond_to?(:embedded, true)
31
- superclass.embedded.each do |embed|
32
- embed.change_context(self)
33
- end
28
+ @__embedded ||= __init_from_superclass(:embedded)
34
29
  end
35
30
  end
36
31
  end
@@ -5,13 +5,13 @@ module HALPresenter
5
5
  attr_reader :resource, :options
6
6
  alias resources resource
7
7
 
8
- def initialize(block)
9
- @__context = eval 'self', block.binding
8
+ def initialize(block, context)
9
+ @context = context
10
10
  define_singleton_method(:evaluate_block, &block)
11
11
  end
12
12
 
13
13
  def update_context(context)
14
- @__context = context
14
+ @context = context
15
15
  end
16
16
 
17
17
  def evaluate(resource, options)
@@ -25,20 +25,20 @@ module HALPresenter
25
25
 
26
26
  private
27
27
 
28
- attr_reader :__context
28
+ attr_reader :context
29
29
 
30
30
  def method_missing(method, *args, &block)
31
- return super unless __context.respond_to?(method)
31
+ return super unless context.respond_to?(method)
32
32
 
33
33
  define_singleton_method(method) do |*a, &b|
34
- __context.public_send(method, *a, &b)
34
+ context.public_send(method, *a, &b)
35
35
  end
36
36
 
37
37
  public_send(method, *args, &block)
38
38
  end
39
39
 
40
40
  def respond_to_missing?(method, _include_private = false)
41
- __context.respond_to?(method) || super
41
+ context.respond_to?(method) || super
42
42
  end
43
43
  end
44
44
  end
@@ -1,4 +1,5 @@
1
1
  require 'hal_presenter/property'
2
+ require 'hal_presenter/super_init'
2
3
 
3
4
  module HALPresenter
4
5
 
@@ -13,24 +14,24 @@ module HALPresenter
13
14
  end
14
15
 
15
16
  module Links
17
+ include SuperInit
16
18
 
17
19
  class Link < HALPresenter::Property
18
20
  attr_reader :type, :deprecation, :profile, :title
19
21
  attr_accessor :templated
20
22
 
23
+ alias rel name
24
+
21
25
  def initialize(rel, value = nil, **kwargs, &block)
22
- if value.nil? && !block_given?
23
- raise 'link must be called with non nil value or be given a block'
24
- end
25
- @type = kwargs[:type]
26
- @deprecation = kwargs[:deprecation]
27
- @profile = kwargs[:profile]
28
- @title = kwargs[:title]
29
- super(rel, value, embed_depth: kwargs[:embed_depth], &block)
30
- end
26
+ @type = kwargs[:type].freeze
27
+ @deprecation = kwargs[:deprecation].freeze
28
+ @profile = kwargs[:profile].freeze
29
+ @title = kwargs[:title].freeze
31
30
 
32
- def rel
33
- name
31
+ curie = kwargs[:curie].to_s
32
+ rel = [curie, rel.to_s].join(':') unless curie.empty?
33
+
34
+ super(rel, value, kwargs.slice(:embed_depth, :context), &block)
34
35
  end
35
36
 
36
37
  def to_h(resource = nil, options = {})
@@ -50,25 +51,21 @@ module HALPresenter
50
51
  end
51
52
 
52
53
  def link(rel, value = nil, **kwargs, &block)
53
- @_links ||= __init_links
54
- @_links = @_links.reject { |link| link.rel == rel }
55
- @_links << Link.new(rel, value, **kwargs, &block)
54
+ if value.nil? && !block_given?
55
+ raise 'link must be called with non nil value or be given a block'
56
+ end
57
+
58
+ kwargs[:context] ||= self
59
+ links.delete_if { |link| link.rel == rel }
60
+ Link.new(rel, value, **kwargs, &block).tap do |link|
61
+ links << link
62
+ end
56
63
  end
57
64
 
58
65
  protected
59
66
 
60
67
  def links
61
- @_links ||= __init_links
62
- end
63
-
64
- private
65
-
66
- def __init_links
67
- return [] unless Class === self
68
- return [] unless superclass.respond_to?(:links, true)
69
- superclass.links.each do |link|
70
- link.change_context(self)
71
- end
68
+ @__links ||= __init_from_superclass(:links)
72
69
  end
73
70
  end
74
71
  end
@@ -2,6 +2,7 @@ module HALPresenter
2
2
  @presenters = {}
3
3
 
4
4
  def HALPresenter.register(model:, presenter:)
5
+ return unless presenter && model
5
6
  @presenters[presenter] = model
6
7
  end
7
8
 
@@ -14,10 +15,15 @@ module HALPresenter
14
15
  end
15
16
 
16
17
  def HALPresenter.lookup_presenter(model)
18
+ lookup_presenters(model).last
19
+ end
20
+
21
+ def HALPresenter.lookup_presenters(model)
17
22
  clazz = model.is_a?(Class) ? model : model.class
18
- presenters = @presenters.select { |d, m| m == clazz }.keys.compact
23
+ presenters = @presenters.select { |_d, m| m == clazz }.keys
19
24
  return presenters unless presenters.empty?
20
- lookup_presenter(clazz.superclass) unless clazz.superclass == BasicObject
25
+ return [] unless clazz < BasicObject
26
+ lookup_presenters(clazz.superclass)
21
27
  end
22
28
 
23
29
  module Model
@@ -0,0 +1,41 @@
1
+ module HALPresenter
2
+ module Namespace
3
+ class Executor
4
+ attr_reader :presenter, :curie
5
+
6
+ def initialize(presenter, curie)
7
+ @presenter = presenter
8
+ @curie = curie
9
+ end
10
+
11
+ def run(block)
12
+ instance_exec(&block) if block
13
+ end
14
+
15
+ private
16
+
17
+ def link(rel, value = nil, **kwargs, &block)
18
+ add_property(:link, rel, value, **kwargs, &block)
19
+ end
20
+
21
+ def embed(rel, value = nil, **kwargs, &block)
22
+ add_property(:embed, rel, value, **kwargs, &block)
23
+ end
24
+
25
+ def add_property(method, rel, value, **kwargs, &block)
26
+ rel = add_curie!(rel, kwargs)
27
+ kwargs[:context] = presenter
28
+ presenter.public_send(method, rel, value, **kwargs, &block)
29
+ end
30
+
31
+ def add_curie!(rel, kwargs)
32
+ ns = kwargs.delete(:curie) { curie }
33
+ "#{ns}:#{rel}"
34
+ end
35
+ end
36
+
37
+ def namespace(curie, &block)
38
+ Executor.new(self, curie).run(block)
39
+ end
40
+ end
41
+ end
@@ -2,13 +2,13 @@ module HALPresenter
2
2
  module Policy
3
3
 
4
4
  def policy(clazz)
5
- @_policy = clazz
5
+ @__policy = clazz
6
6
  end
7
7
 
8
8
  protected
9
9
 
10
10
  def policy_class
11
- @_policy ||= __init_policy
11
+ @__policy ||= __init_policy
12
12
  end
13
13
 
14
14
  private
@@ -2,29 +2,41 @@ require 'hal_presenter/lazy_evaluator'
2
2
 
3
3
  module HALPresenter
4
4
  class Property
5
-
6
5
  attr_reader :name, :embed_depth
7
6
 
8
- def initialize(name, value = nil, embed_depth: nil, &block)
7
+ def initialize(name, value = nil, **kwargs, &block)
9
8
  @name = name.to_sym
10
- @value = value
11
- @embed_depth = embed_depth
12
- @lazy = block_given? && LazyEvaluator.new(block)
9
+ @value = value.freeze
10
+ @embed_depth = kwargs[:embed_depth].freeze
11
+ @context = kwargs[:context]
12
+ @lazy = block_given? ? LazyEvaluator.new(block, @context) : nil
13
13
  end
14
14
 
15
15
  def value(resource = nil, options = nil)
16
16
  if @lazy
17
17
  @lazy.evaluate(resource, options)
18
- elsif resource && @value.nil?
19
- resource.public_send(name) if resource.respond_to?(name)
20
- else
18
+ elsif @value
21
19
  @value
20
+ elsif resource&.respond_to? name_without_curie
21
+ resource.public_send(name_without_curie)
22
22
  end
23
23
  end
24
24
 
25
25
  def change_context(context)
26
- return unless @lazy
27
- @lazy.update_context(context)
26
+ @context = context
27
+ @lazy.update_context(context) if @lazy
28
+ self
29
+ end
30
+
31
+ private
32
+
33
+ def initialize_copy(source)
34
+ @lazy = source.instance_variable_get(:@lazy).clone
35
+ super
36
+ end
37
+
38
+ def name_without_curie
39
+ @name_without_curie ||= name.to_s.split(':', 2).last
28
40
  end
29
41
  end
30
42
  end
@@ -21,13 +21,13 @@ module HALPresenter
21
21
  end
22
22
 
23
23
  def post_serialize(&block)
24
- @_post_serialize_hook = Hook.new(&block)
24
+ @__post_serialize_hook = Hook.new(&block)
25
25
  end
26
26
 
27
27
  protected
28
28
 
29
29
  def post_serialize_hook
30
- @_post_serialize_hook ||= __init_post_serialize_hook
30
+ @__post_serialize_hook ||= __init_post_serialize_hook
31
31
  end
32
32
 
33
33
  private
@@ -6,7 +6,7 @@ module HALPresenter
6
6
  def self.to_hal(resource, options = {})
7
7
  raise Serializer::Error, "Resource is nil" if resource.nil?
8
8
  presenter = options.delete(:presenter)
9
- presenter ||= HALPresenter.lookup_presenter(resource)&.last
9
+ presenter ||= HALPresenter.lookup_presenter(resource)
10
10
  raise Serializer::Error, "No presenter for #{resource.class}" unless presenter
11
11
  presenter.to_hal(resource, options)
12
12
  end
@@ -14,7 +14,7 @@ module HALPresenter
14
14
  def self.to_collection(resources, options = {})
15
15
  raise Serializer::Error, "resources is nil" if resources.nil?
16
16
  presenter = options.delete(:presenter)
17
- presenter ||= HALPresenter.lookup_presenter(resources.first)&.last
17
+ presenter ||= HALPresenter.lookup_presenter(resources.first)
18
18
  raise Serializer::Error, "No presenter for #{resources.first.class}" unless presenter
19
19
  presenter.to_collection(resources, options)
20
20
  end
@@ -69,13 +69,13 @@ module HALPresenter
69
69
  Pagination.paginate!(serialized, resources) if options[:paginate]
70
70
 
71
71
  # Embedded from collection block
72
- embedded = _serialize_embedded(embedded, resources, policy, options)
73
- serialized[:_embedded] = embedded[:_embedded] || {}
72
+ serialized.merge! _serialize_embedded(embedded, resources, policy, options)
74
73
 
75
74
  # Embedded resources
76
75
  options[:_depth] += 1
77
76
  serialized_resources = resources.map { |resource| to_hash(resource, options) }
78
- serialized[:_embedded].merge!({properties.name => serialized_resources })
77
+ serialized[:_embedded] ||= {}
78
+ serialized[:_embedded].merge!(properties.name => serialized_resources)
79
79
  end
80
80
  end
81
81
 
@@ -168,7 +168,7 @@ module HALPresenter
168
168
  if resource.is_a? Array
169
169
  _serialize_embedded_collection(resource, presenter, options)
170
170
  else
171
- presenter ||= HALPresenter.lookup_presenter(resource).first
171
+ presenter ||= HALPresenter.lookup_presenter(resource)
172
172
  presenter.to_hash(resource, options)
173
173
  end
174
174
  end
@@ -178,7 +178,7 @@ module HALPresenter
178
178
 
179
179
  def _serialize_embedded_collection(resources, presenter, options)
180
180
  clazz = resources.first.class
181
- presenter ||= HALPresenter.lookup_presenter(clazz)&.first
181
+ presenter ||= HALPresenter.lookup_presenter(clazz)
182
182
  if presenter.nil?
183
183
  raise Serializer::Error,
184
184
  "No presenter specified to handle serializing embedded #{clazz}"
@@ -0,0 +1,20 @@
1
+ module HALPresenter
2
+ module SuperInit
3
+ private
4
+
5
+ def __init_from_superclass(method, default: [])
6
+ return default unless Class === self
7
+ return default unless superclass.respond_to?(method, true)
8
+
9
+ if default.respond_to? :each
10
+ superclass.send(method).map do |prop|
11
+ prop.clone.change_context(self)
12
+ end
13
+ else
14
+ prop = superclass.send(method)
15
+ return default unless prop
16
+ prop.clone.change_context(self)
17
+ end
18
+ end
19
+ end
20
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hal_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sammy Henningsson
@@ -30,7 +30,7 @@ cert_chain:
30
30
  ZMhjYR7sRczGJx+GxGU2EaR0bjRsPVlC4ywtFxoOfRG3WaJcpWGEoAoMJX6Z0bRv
31
31
  M40=
32
32
  -----END CERTIFICATE-----
33
- date: 2019-03-08 00:00:00.000000000 Z
33
+ date: 2019-07-10 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: rake
@@ -169,12 +169,14 @@ files:
169
169
  - lib/hal_presenter/lazy_evaluator.rb
170
170
  - lib/hal_presenter/links.rb
171
171
  - lib/hal_presenter/model.rb
172
+ - lib/hal_presenter/namespace.rb
172
173
  - lib/hal_presenter/pagination.rb
173
174
  - lib/hal_presenter/policy.rb
174
175
  - lib/hal_presenter/policy/dsl.rb
175
176
  - lib/hal_presenter/property.rb
176
177
  - lib/hal_presenter/serialize_hooks.rb
177
178
  - lib/hal_presenter/serializer.rb
179
+ - lib/hal_presenter/super_init.rb
178
180
  homepage: https://github.com/sammyhenningsson/hal_presenter
179
181
  licenses:
180
182
  - MIT
metadata.gz.sig CHANGED
Binary file