yaks 0.6.0.alpha.1 → 0.6.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +46 -0
  3. data/lib/yaks/attributes.rb +45 -0
  4. data/lib/yaks/collection_resource.rb +1 -45
  5. data/lib/yaks/config/dsl.rb +15 -6
  6. data/lib/yaks/config.rb +1 -1
  7. data/lib/yaks/configurable.rb +20 -0
  8. data/lib/yaks/default_policy.rb +0 -8
  9. data/lib/yaks/errors.rb +3 -0
  10. data/lib/yaks/format/hal.rb +13 -2
  11. data/lib/yaks/format/halo.rb +29 -0
  12. data/lib/yaks/mapper/association.rb +18 -13
  13. data/lib/yaks/mapper/association_mapper.rb +1 -1
  14. data/lib/yaks/mapper/attribute.rb +1 -3
  15. data/lib/yaks/mapper/class_methods.rb +24 -16
  16. data/lib/yaks/mapper/config.rb +13 -28
  17. data/lib/yaks/mapper/control.rb +38 -0
  18. data/lib/yaks/mapper/has_many.rb +4 -8
  19. data/lib/yaks/mapper/link.rb +10 -2
  20. data/lib/yaks/mapper.rb +11 -2
  21. data/lib/yaks/resource/control.rb +11 -0
  22. data/lib/yaks/resource/link.rb +1 -7
  23. data/lib/yaks/resource.rb +9 -13
  24. data/lib/yaks/runner.rb +2 -4
  25. data/lib/yaks/serializer.rb +12 -0
  26. data/lib/yaks/stateful_builder.rb +54 -0
  27. data/lib/yaks/version.rb +1 -1
  28. data/lib/yaks.rb +16 -7
  29. data/spec/acceptance/acceptance_spec.rb +14 -4
  30. data/spec/acceptance/models.rb +9 -0
  31. data/spec/integration/map_to_resource_spec.rb +1 -1
  32. data/spec/json/confucius.halo.json +80 -0
  33. data/spec/spec_helper.rb +5 -0
  34. data/spec/support/shared_contexts.rb +1 -1
  35. data/spec/unit/yaks/attributes_spec.rb +65 -0
  36. data/spec/unit/yaks/collection_mapper_spec.rb +1 -1
  37. data/spec/unit/yaks/collection_resource_spec.rb +7 -25
  38. data/spec/unit/yaks/config/dsl_spec.rb +5 -0
  39. data/spec/unit/yaks/config_spec.rb +2 -1
  40. data/spec/unit/yaks/configurable_spec.rb +25 -0
  41. data/spec/unit/yaks/default_policy_spec.rb +1 -7
  42. data/spec/unit/yaks/format/collection_json_spec.rb +1 -1
  43. data/spec/unit/yaks/format/hal_spec.rb +2 -2
  44. data/spec/unit/yaks/format/html_spec.rb +5 -0
  45. data/spec/unit/yaks/format/json_api_spec.rb +1 -1
  46. data/spec/unit/yaks/format_spec.rb +1 -5
  47. data/spec/unit/yaks/mapper/association_mapper_spec.rb +2 -2
  48. data/spec/unit/yaks/mapper/association_spec.rb +27 -3
  49. data/spec/unit/yaks/mapper/class_methods_spec.rb +17 -1
  50. data/spec/unit/yaks/mapper/config_spec.rb +16 -8
  51. data/spec/unit/yaks/mapper/has_many_spec.rb +15 -2
  52. data/spec/unit/yaks/mapper/has_one_spec.rb +1 -1
  53. data/spec/unit/yaks/mapper/link_spec.rb +12 -2
  54. data/spec/unit/yaks/mapper_spec.rb +51 -22
  55. data/spec/unit/yaks/resource/link_spec.rb +2 -1
  56. data/spec/unit/yaks/resource_spec.rb +16 -9
  57. data/spec/unit/yaks/runner_spec.rb +22 -2
  58. data/spec/unit/yaks/serializer_spec.rb +20 -0
  59. data/spec/unit/yaks/stateful_builder_spec.rb +41 -0
  60. data/yaks.gemspec +1 -0
  61. metadata +39 -11
  62. data/lib/yaks/fp/hash_updatable.rb +0 -19
  63. data/lib/yaks/fp/updatable.rb +0 -17
  64. data/spec/unit/yaks/fp/hash_updatable_spec.rb +0 -22
  65. data/spec/unit/yaks/fp/updatable_spec.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1363b84d5c4a3fc9a834c05015bd3b1f0a00450b
4
- data.tar.gz: 90f37a7f613072a718e95023fe5475481096b724
3
+ metadata.gz: 79d98824107ec7c700f39b7776dd1ce517f3283b
4
+ data.tar.gz: 10a45b5d3b2a73054232b63b4b2d70b5dd83c87e
5
5
  SHA512:
6
- metadata.gz: 81db95d4be9d95499da0205e39085611521fdff084abff9902e2cceb8c9677ef24294d912bc537b4874e52008a9694f76f13478af5fcd959931a153a1f171480
7
- data.tar.gz: 73897cc179e778e280ce92197df35084a78e737dee498b9579e6132c8fbdbcff2725dea25ae5394747df8866f2372677c18562c0e21c98f628d32fb72aca33b1
6
+ metadata.gz: 8766e6b07b209e32f739caaa1e965d88a1615501705f9b8e6f6d857d8d4149816aa34ab846b0e37f9605a2ee5fc5359faed766e92f6550efda42bc5d9b4f3ebb
7
+ data.tar.gz: a65eb2384e11a8d9379f558afbaadffc67fc72cfa71fdd19812c905de84884d2a91f57366475a4da636ba987052a58c6f6e4986d9feda24226b153ed108fc22a
data/Rakefile CHANGED
@@ -1,3 +1,49 @@
1
1
  load '../rakelib/shared.rake'
2
2
 
3
3
  gem_tasks(:yaks)
4
+
5
+
6
+ task :mutant_chunked do
7
+ [
8
+ Yaks::Attributes,
9
+ Yaks::Attributes::InstanceMethods,
10
+ Yaks::CollectionMapper,
11
+ Yaks::CollectionResource,
12
+ Yaks::Config,
13
+ Yaks::Config::DSL,
14
+ Yaks::Configurable,
15
+ Yaks::Configurable::ClassMethods,
16
+ Yaks::StatefulBuilder,
17
+ Yaks::DefaultPolicy,
18
+ Yaks::FP,
19
+ Yaks::FP::Callable,
20
+ Yaks::Format,
21
+ Yaks::Format::CollectionJson,
22
+ Yaks::Format::Hal,
23
+ Yaks::Format::Halo,
24
+ Yaks::Format::JsonAPI,
25
+ Yaks::Mapper::AssociationMapper,
26
+ Yaks::Mapper::Attribute,
27
+ Yaks::Mapper::Config,
28
+ Yaks::Mapper::Control,
29
+ Yaks::Mapper::Control::Field,
30
+ Yaks::Mapper::HasOne,
31
+ Yaks::NullResource,
32
+ Yaks::Primitivize,
33
+ Yaks::Resource::Link,
34
+ Yaks::Util,
35
+ Yaks::Serializer,
36
+ Yaks::Runner,
37
+ Yaks::Resource,
38
+ Yaks::Mapper::Link,
39
+ Yaks::Mapper::HasMany,
40
+ Yaks::Mapper::ClassMethods,
41
+ Yaks::Mapper::Association,
42
+ Yaks::Mapper,
43
+ # Yaks::Format::HTML,
44
+ ].each do |space|
45
+ puts space
46
+ ENV['PATTERN'] = "#{space}"
47
+ Rake::Task["mutant"].execute
48
+ end
49
+ end
@@ -0,0 +1,45 @@
1
+ module Yaks
2
+ class Attributes < Module
3
+ attr_reader :defaults, :attributes
4
+
5
+ def initialize(*attrs)
6
+ @defaults = attrs.last.instance_of?(Hash) ? attrs.pop : {}
7
+ @attributes = attrs + @defaults.keys
8
+ end
9
+
10
+ def add(*attrs)
11
+ defaults = attrs.last.instance_of?(Hash) ? attrs.pop : {}
12
+ self.class.new(*[*(attributes+attrs), @defaults.merge(defaults)])
13
+ end
14
+
15
+ def included(descendant)
16
+ descendant.module_exec(self) do |this|
17
+ include InstanceMethods,
18
+ Anima.new(*this.attributes),
19
+ Anima::Update
20
+
21
+ this.attributes.each do |attr|
22
+ define_method attr do |value = Undefined|
23
+ if value.equal? Undefined
24
+ instance_variable_get("@#{attr}")
25
+ else
26
+ update(attr => value)
27
+ end
28
+ end
29
+ end
30
+
31
+ define_singleton_method(:attributes) { this }
32
+ end
33
+ end
34
+
35
+ module InstanceMethods
36
+ def initialize(attributes = {})
37
+ super(self.class.attributes.defaults.merge(attributes))
38
+ end
39
+
40
+ def append_to(type, *objects)
41
+ update(type => instance_variable_get("@#{type}") + objects)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -15,55 +15,11 @@ module Yaks
15
15
  # In the second case a collection has a single "subresource", being its
16
16
  # members.
17
17
  class CollectionResource < Resource
18
- include Equalizer.new(:type, :links, :attributes, :members, :collection_rel)
19
- include FP::HashUpdatable.new(:type, :links, :attributes, :members, :collection_rel)
20
- include Enumerable
18
+ include attributes.add(members: [], collection_rel: 'members')
21
19
 
22
20
  extend Forwardable
23
-
24
- # @!attribute [r] type
25
- # @return [String]
26
- # @!attribute [r] links
27
- # @return [Array]
28
- # @!attribute [r] members
29
- # @return [Array]
30
- # @!attribute [r] collection_rel
31
- # @return [String]
32
- attr_reader :type, :links, :members, :collection_rel
33
-
34
21
  def_delegators :members, :each
35
22
 
36
- # @param [Hash] options
37
- # @return [CollectionResource]
38
- def initialize(options)
39
- super
40
- @members = options.fetch(:members, [])
41
- @collection_rel = options.fetch(:collection_rel, 'members')
42
- end
43
-
44
- # Make a CollectionResource quack like a resource.
45
- #
46
- # At the moment this is only for HAL, which always assumes
47
- # a singular resource at the top level, this way it can treat
48
- # whatever it gets as a single resource with links and subresources,
49
- # we just push the collection down one level.
50
- #
51
- # Once inside subresources the HAL format does check if a resource
52
- # is a collection, since there it does make a distinction, and because
53
- # in that case it will iterate with each/map rather than calling subresources,
54
- # this doesn't cause infinite recursion. Not very pretty, needs looking at.
55
- #
56
- # :(
57
- #
58
- # @return [Hash]
59
- def subresources
60
- if any?
61
- { collection_rel => self }
62
- else
63
- {}
64
- end
65
- end
66
-
67
23
  # @return [Boolean]
68
24
  def collection?
69
25
  true
@@ -50,21 +50,30 @@ module Yaks
50
50
  config.default_format = format
51
51
  end
52
52
 
53
- # Configure JSON serializer
53
+ # Configure serializer for specific output format, e.g. JSON
54
54
  #
55
- # Defaults to JSON.pretty_generate
55
+ # This will override the default registered serializer. Note
56
+ # that extension gems can register their own serializers, see
57
+ # Yaks::Serializer.register
56
58
  #
57
59
  # @example
58
60
  #
59
61
  # yaks = Yaks.new do
60
- # json_serializer &Oj.method(:dump)
62
+ # serializer :json, &Oj.method(:dump)
61
63
  # end
62
64
  #
63
- # @param [Proc] block
65
+ # @type [Symbol] type
66
+ # Output format
67
+ # @param [Proc] serializer
64
68
  # Serialization procedure
65
69
  #
66
- def json_serializer(&block)
67
- config.serializers[:json] = block
70
+ def serializer(type, &serializer)
71
+ config.serializers[type] = serializer
72
+ end
73
+
74
+ # @deprecated
75
+ def json_serializer(&serializer)
76
+ serializer(:json, &serializer)
68
77
  end
69
78
 
70
79
  %w[before after around skip].map(&:intern).each do |hook_type|
data/lib/yaks/config.rb CHANGED
@@ -36,7 +36,7 @@ module Yaks
36
36
  @default_format = :hal
37
37
  @policy_options = {}
38
38
  @primitivize = Primitivize.create
39
- @serializers = {}
39
+ @serializers = Serializer.all.dup
40
40
  @hooks = []
41
41
 
42
42
  DSL.new(self, &blk)
@@ -0,0 +1,20 @@
1
+ module Yaks
2
+ module Configurable
3
+ def self.included(descendant)
4
+ descendant.instance_eval do
5
+ extend ClassMethods
6
+ end
7
+ end
8
+
9
+ module ClassMethods
10
+ def config_method(name, options)
11
+ define_method name do |*args, &block|
12
+ append_to(
13
+ options.fetch(:append_to),
14
+ options.fetch(:create).create(*args, &block)
15
+ )
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -88,13 +88,5 @@ module Yaks
88
88
  URITemplate.new(@options[:rel_template]).expand(rel: relname)
89
89
  end
90
90
 
91
- # @param format_class [Class]
92
- # @return [#call] format_class
93
- def serializer_for_format(format_class)
94
- {
95
- json: JSON.method(:pretty_generate),
96
- html: :to_html.to_proc
97
- }.fetch(format_class.serializer)
98
- end
99
91
  end
100
92
  end
@@ -0,0 +1,3 @@
1
+ module Yaks
2
+ IllegalState = Class.new(StandardError)
3
+ end
@@ -33,8 +33,19 @@ module Yaks
33
33
  # resource.
34
34
  #
35
35
  result = resource.attributes
36
- result = result.merge(:_links => serialize_links(resource.links)) unless resource.links.empty?
37
- result = result.merge(:_embedded => serialize_embedded(resource.subresources)) unless resource.subresources.empty?
36
+
37
+ if resource.links.any?
38
+ result = result.merge(_links: serialize_links(resource.links))
39
+ end
40
+
41
+ if resource.collection?
42
+ result = result.merge(_embedded:
43
+ serialize_embedded(resource.collection_rel => resource))
44
+ elsif resource.subresources.any?
45
+ result = result.merge(_embedded:
46
+ serialize_embedded(resource.subresources))
47
+ end
48
+
38
49
  result
39
50
  end
40
51
 
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module Yaks
4
+ class Format
5
+ # Extension of Hal loosely based on the example by Mike Kelly given at
6
+ # https://gist.github.com/mikekelly/893552
7
+ class Halo < Hal
8
+ register :halo, :json, 'application/halo+json'
9
+
10
+ def serialize_resource(resource)
11
+ if resource.controls.any?
12
+ super.merge(_controls: serialize_controls(resource.controls))
13
+ else
14
+ super
15
+ end
16
+ end
17
+
18
+ def serialize_controls(controls)
19
+ controls.each_with_object({}) do |control, result|
20
+ result[control.name] = serialize_control(control)
21
+ end
22
+ end
23
+
24
+ def serialize_control(control)
25
+ control.to_h.merge(fields: control.fields.map(&:to_h))
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,18 +1,23 @@
1
1
  module Yaks
2
2
  class Mapper
3
3
  class Association
4
- include Equalizer.new(:name, :child_mapper, :rel, :href, :link_if)
5
- include Util
6
-
7
- attr_reader :name, :child_mapper, :rel, :href, :link_if
8
-
9
- def initialize(options)
10
- @name = options.fetch(:name)
11
- @child_mapper = options.fetch(:mapper, Undefined)
12
- @rel = options.fetch(:rel, Undefined)
13
-
14
- @href = options.fetch(:href, Undefined)
15
- @link_if = options.fetch(:link_if, Undefined)
4
+ include Attributes.new(
5
+ name: Undefined,
6
+ item_mapper: Undefined,
7
+ rel: Undefined,
8
+ href: Undefined,
9
+ link_if: Undefined
10
+ ),
11
+ Util
12
+
13
+ def self.create(name, options = {})
14
+ if options.key?(:mapper)
15
+ options = options.dup
16
+ mapper = options.delete(:mapper)
17
+ options[:item_mapper] = mapper
18
+ end
19
+ options[:name] = name
20
+ new(options)
16
21
  end
17
22
 
18
23
  def add_to_resource(resource, parent_mapper, context)
@@ -34,7 +39,7 @@ module Yaks
34
39
 
35
40
  # support for HasOne and HasMany
36
41
  def resolve_association_mapper(policy)
37
- return child_mapper unless child_mapper.equal?(Undefined)
42
+ return item_mapper unless item_mapper.equal?(Undefined)
38
43
  policy.derive_mapper_from_association(self)
39
44
  end
40
45
 
@@ -25,7 +25,7 @@ module Yaks
25
25
  end
26
26
 
27
27
  def add_link(resource)
28
- Link.new(rel, association.href, {})
28
+ Link.create(rel, association.href)
29
29
  .add_to_resource(resource, parent_mapper, nil)
30
30
  # Yaks::Mapper::Link doesn't do anything with the context, making it
31
31
  # hard to test that we pass it a context. Passing nil for now, until
@@ -1,9 +1,7 @@
1
1
  module Yaks
2
2
  class Mapper
3
3
  class Attribute
4
- include Equalizer.new(:name)
5
-
6
- attr_reader :name
4
+ include Concord::Public.new(:name)
7
5
 
8
6
  def initialize(name)
9
7
  @name = name
@@ -3,9 +3,22 @@
3
3
  module Yaks
4
4
  class Mapper
5
5
  module ClassMethods
6
- include Forwardable
7
- include Util
8
- include FP
6
+ include Forwardable,
7
+ Util,
8
+ FP
9
+
10
+ def config(value = Undefined)
11
+ if value.equal? Undefined
12
+ @config
13
+ else
14
+ raise if value.nil?
15
+ @config = value
16
+ end
17
+ end
18
+
19
+ def inherited(child)
20
+ child.config(config)
21
+ end
9
22
 
10
23
  CONFIG_METHODS = [
11
24
  :type,
@@ -13,22 +26,17 @@ module Yaks
13
26
  :link,
14
27
  :profile,
15
28
  :has_one,
16
- :has_many
29
+ :has_many,
30
+ :control
17
31
  ]
18
32
 
19
- def config
20
- @config ||= Config.new nil, [], [], []
21
- @config = yield(@config) if block_given?
22
- @config
23
- end
24
-
25
- def inherited(child)
26
- child.config { @config }
27
- end
28
-
29
33
  CONFIG_METHODS.each do |method_name|
30
- define_method method_name do |*args|
31
- config &send_with_args(method_name, *args)
34
+ define_method method_name do |*args, &block|
35
+ if args.empty?
36
+ config.public_send(method_name, *args, &block)
37
+ else
38
+ config(config.public_send(method_name, *args, &block))
39
+ end
32
40
  end
33
41
  end
34
42
 
@@ -1,17 +1,10 @@
1
1
  module Yaks
2
2
  class Mapper
3
3
  class Config
4
- include Equalizer.new(:type, :attributes, :links, :associations)
5
- include FP::Updatable.new(:type, :attributes, :links, :associations)
6
-
7
- attr_reader :links, :associations
8
-
9
- def initialize(type, attributes, links, associations)
10
- @type = type
11
- @attributes = attributes
12
- @links = links
13
- @associations = associations
14
- end
4
+ include Attributes.new(
5
+ type: nil, attributes: [], links: [], associations: [], controls: []
6
+ ),
7
+ Configurable
15
8
 
16
9
  def type(type = Undefined)
17
10
  return @type if type.equal?(Undefined)
@@ -20,25 +13,17 @@ module Yaks
20
13
 
21
14
  def attributes(*attrs)
22
15
  return @attributes if attrs.empty?
23
- update(attributes: @attributes + attrs.map(&Attribute.method(:new)))
24
- end
25
-
26
- def link(rel, template, options = {})
27
- update(links: @links + [Link.new(rel, template, options)])
28
- end
29
-
30
- def add_association(type, name, options)
31
- update(associations: @associations + [type.new(options.merge(name: name))])
32
- end
33
-
34
- def has_one(name, options = {})
35
- add_association(HasOne, name, options)
36
- end
37
-
38
- def has_many(name, options = {})
39
- add_association(HasMany, name, options)
16
+ append_to(:attributes, *attrs.map(&Attribute.method(:new)))
40
17
  end
41
18
 
19
+ config_method :link, create: Link, append_to: :links
20
+ config_method :has_one, create: HasOne, append_to: :associations
21
+ config_method :has_many, create: HasMany, append_to: :associations
22
+ config_method :attribute, create: Attribute, append_to: :attributes
23
+ config_method :attribute, create: Attribute, append_to: :attributes
24
+ config_method :control,
25
+ create: StatefulBuilder.new(Control, Control.anima.attribute_names + [:field]),
26
+ append_to: :controls
42
27
  end
43
28
  end
44
29
  end
@@ -0,0 +1,38 @@
1
+ module Yaks
2
+ class Mapper
3
+ class Control
4
+ include Attributes.new(
5
+ name: nil, href: nil, title: nil, method: nil, media_type: nil, fields: []
6
+ ),
7
+ Configurable
8
+
9
+ def self.create(name = nil, options = {})
10
+ new({name: name}.merge(options))
11
+ end
12
+
13
+ def add_to_resource(resource, _parent_mapper, _context)
14
+ resource.add_control(
15
+ ::Yaks::Resource::Control.new(to_h.merge(fields: fields.map(&:to_resource_control_field)))
16
+ )
17
+ end
18
+
19
+ class Field
20
+ include Attributes.new(:name, label: nil, type: "text", value: nil)
21
+
22
+ def self.create(*args)
23
+ attrs = args.last.is_a?(Hash) ? args.pop : {}
24
+ if name = args.shift
25
+ attrs = attrs.merge(name: name)
26
+ end
27
+ new(attrs)
28
+ end
29
+
30
+ def to_resource_control_field
31
+ Yaks::Resource::Control::Field.new(to_h)
32
+ end
33
+ end
34
+
35
+ config_method :field, create: Field, append_to: :fields
36
+ end
37
+ end
38
+ end
@@ -1,12 +1,8 @@
1
1
  module Yaks
2
2
  class Mapper
3
3
  class HasMany < Association
4
- include Util
5
-
6
- def initialize(options)
7
- super
8
- @collection_mapper = options.fetch(:collection_mapper, Undefined)
9
- end
4
+ include Util,
5
+ attributes.add(collection_mapper: Undefined)
10
6
 
11
7
  def map_resource(collection, context)
12
8
  return NullResource.new(collection: true) if collection.nil?
@@ -16,9 +12,9 @@ module Yaks
16
12
  collection_mapper(collection, policy).new(context).call(collection)
17
13
  end
18
14
 
19
- def collection_mapper(collection, policy)
15
+ def collection_mapper(collection = nil, policy = nil)
20
16
  return @collection_mapper unless @collection_mapper.equal? Undefined
21
- policy.derive_mapper_from_object(collection)
17
+ policy.derive_mapper_from_object(collection) if policy && collection
22
18
  end
23
19
 
24
20
  def singular_name
@@ -25,11 +25,15 @@ module Yaks
25
25
  # it will receive the mapper instance as argument. Otherwise it is evaluated in the mapper context
26
26
  class Link
27
27
  extend Forwardable
28
- include Concord.new(:rel, :template, :options)
28
+ include Attributes.new(:rel, :template, options: {})
29
29
  include Util
30
30
 
31
31
  def_delegators :uri_template, :expand_partial
32
32
 
33
+ def self.create(rel, template, options = {})
34
+ new(rel: rel, template: template, options: options)
35
+ end
36
+
33
37
  def add_to_resource(resource, mapper, _context)
34
38
  resource_link = map_to_resource_link(mapper)
35
39
  return resource unless resource_link
@@ -70,7 +74,11 @@ module Yaks
70
74
  uri = expand_with(mapper.method(:load_attribute))
71
75
  return if uri.nil?
72
76
 
73
- Resource::Link.new(rel, uri, resource_link_options(mapper))
77
+ Resource::Link.new(
78
+ rel: rel,
79
+ uri: uri,
80
+ options: resource_link_options(mapper)
81
+ )
74
82
  end
75
83
 
76
84
  def expand_with(lookup)
data/lib/yaks/mapper.rb CHANGED
@@ -6,7 +6,9 @@ module Yaks
6
6
  include Util, FP
7
7
 
8
8
  def_delegators 'self.class', :config
9
- def_delegators :config, :attributes, :links, :associations
9
+ def_delegators :config, :attributes, :links, :associations, :controls
10
+
11
+ config Config.new
10
12
 
11
13
  attr_reader :object, :context
12
14
 
@@ -41,7 +43,8 @@ module Yaks
41
43
 
42
44
  [ :map_attributes,
43
45
  :map_links,
44
- :map_subresources
46
+ :map_subresources,
47
+ :map_controls
45
48
  ].inject(Resource.new(type: mapper_name)) do |resource, method|
46
49
  send(method, resource)
47
50
  end
@@ -71,5 +74,11 @@ module Yaks
71
74
  association.add_to_resource(res, self, context)
72
75
  end
73
76
  end
77
+
78
+ def map_controls(resource)
79
+ controls.inject(resource) do |res, control|
80
+ control.add_to_resource(res, self, context)
81
+ end
82
+ end
74
83
  end
75
84
  end
@@ -0,0 +1,11 @@
1
+ module Yaks
2
+ class Resource
3
+ class Control
4
+ include Yaks::Mapper::Control.attributes
5
+
6
+ class Field
7
+ include Yaks::Mapper::Control::Field.attributes
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,13 +1,7 @@
1
1
  module Yaks
2
2
  class Resource
3
3
  class Link
4
- include Equalizer.new(:rel, :uri, :options)
5
-
6
- attr_reader :rel, :uri, :options
7
-
8
- def initialize(rel, uri, options)
9
- @rel, @uri, @options = rel, uri, options
10
- end
4
+ include Attributes.new(:rel, :uri, options: {})
11
5
 
12
6
  def title
13
7
  options[:title]
data/lib/yaks/resource.rb CHANGED
@@ -1,17 +1,9 @@
1
1
  module Yaks
2
2
  class Resource
3
- include Equalizer.new(:type, :links, :attributes, :subresources)
4
- include FP::HashUpdatable.new(:type, :links, :attributes, :subresources)
5
- include Enumerable
6
-
7
- attr_reader :type, :attributes, :links, :subresources
8
-
9
- def initialize(options = {})
10
- @type = options.fetch(:type, nil)
11
- @attributes = options.fetch(:attributes, {})
12
- @links = options.fetch(:links, [])
13
- @subresources = options.fetch(:subresources, {})
14
- end
3
+ include Attributes.new(
4
+ type: nil, links: [], attributes: {}, subresources: {}, controls: []
5
+ ),
6
+ Enumerable
15
7
 
16
8
  def [](attr)
17
9
  attributes[attr]
@@ -41,7 +33,11 @@ module Yaks
41
33
  end
42
34
 
43
35
  def add_link(link)
44
- update(links: @links + [link])
36
+ append_to(:links, link)
37
+ end
38
+
39
+ def add_control(control)
40
+ append_to(:controls, control)
45
41
  end
46
42
 
47
43
  def add_subresource(rel, subresource)