hal_presenter 1.0.0 → 1.1.0

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: 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