Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement setters and getters #21

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
11 changes: 11 additions & 0 deletions examples/usual/example1/season.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,22 @@ class Season < Datory::Base
# uuid! :serialId, to: :serial_id

integer! :number
string! :code

# many! :episodes, include: Episode

date! :premieredOn, to: :premiered_on
date? :endedOn, to: :ended_on

# deserialize
getter :code do |attributes:|
"s#{attributes.fetch(:number)}"
end

# serialize
setter :code do |attributes:|
"s#{attributes.fetch(:number)}"
end
end
end
end
11 changes: 11 additions & 0 deletions examples/usual/example2/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,24 @@ class Product < Datory::Base
uuid! :id

string! :title
string! :formattedTitle, to: :formatted_title

money! :price
money? :discount

integer! :quantity, min: 1, max: 10

duration? :installmentDuration, to: :installment_duration

# deserialize
getter :formattedTitle do |attributes:|
"The New #{attributes.fetch(:title)} (from getter)"
end

# serialize
setter :formatted_title do |attributes:|
"The New #{attributes.fetch(:title)} (from setter)"
end
end
end
end
16 changes: 16 additions & 0 deletions examples/usual/example3/language.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Language < Datory::Base
uuid! :id

string! :name
string? :fullName, to: :full_name

# TODO: Need to prepare this example:
# {
Expand All @@ -32,6 +33,21 @@ class Language < Datory::Base
one? :lastEOLVersion, to: :last_eol, include: Version

many? :previousVersions, to: :previous, include: Version

# deserialize
getter :fullName do |**|
nil
end

# serialize
setter :full_name do |attributes:|
language_name = attributes.fetch(:name)
current_version_name = attributes.dig(:current, :name)

next language_name if current_version_name.blank?

"#{language_name} (#{current_version_name})"
end
end
end
end
4 changes: 4 additions & 0 deletions lib/datory/attributes/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ def internal_names
map { |attribute| attribute.to.name }
end

def external_names
map { |attribute| attribute.from.name }
end

def include_class_exist?
@include_class_exist ||= filter do |attribute| # rubocop:disable Performance/Count
include_class = attribute.to.include_class
Expand Down
5 changes: 4 additions & 1 deletion lib/datory/attributes/descriptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ def describe(service_class_name:, collection_of_attributes:) # rubocop:disable M
row << attribute.from.type
row << attribute.to.name
row << attribute.to.type
row << (include_class if include_class <= Datory::Base) if collection_of_attributes.include_class_exist?

if collection_of_attributes.include_class_exist? && !include_class.nil?
row << (include_class if include_class.respond_to?(:<=) && include_class <= Datory::Base)
end

rows << row
end
Expand Down
29 changes: 23 additions & 6 deletions lib/datory/attributes/serialization/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def self.to_hash(...)
new.to_hash(...)
end

def prepare(data)
def prepare(data, collection_of_attributes)
if data.is_a?(Hash)
build(data.deep_dup)
build(collection_of_attributes, data.deep_dup)
else
data
end
Expand All @@ -28,17 +28,34 @@ def to_hash(data)
end
end

def build(attributes = {}) # rubocop:disable Metrics/MethodLength
attributes.each do |key, value|
private

def define_setter(key, value)
self.class.send(:attr_accessor, key)

instance_variable_set(:"@#{key}", value)

self
end

def build(collection_of_attributes, attributes = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
additional_attributes = collection_of_attributes.internal_names.difference(attributes.keys).to_h do |key|
[key, nil]
end

attributes.merge(additional_attributes).each do |key, value|
self.class.send(:attr_accessor, key)

instance_variable_set(:"@#{key}", value)

if value.is_a?(Array)
value.map! { |item| Datory::Attributes::Serialization::Model.prepare(item) }
value.map! { |item| Datory::Attributes::Serialization::Model.prepare(item, collection_of_attributes) }
instance_variable_set(:"@#{key}", value)
elsif value.is_a?(Hash)
instance_variable_set(:"@#{key}", Datory::Attributes::Serialization::Model.prepare(value))
instance_variable_set(
:"@#{key}",
Datory::Attributes::Serialization::Model.prepare(value, collection_of_attributes)
)
else
instance_variable_set(:"@#{key}", value)
end
Expand Down
4 changes: 2 additions & 2 deletions lib/datory/attributes/workspace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Attributes
module Workspace
private

def serialize(model:, collection_of_attributes:)
def serialize(model:, collection_of_attributes:, **)
super

return nil if model.nil? # NOTE: When `one` is optional and not passed
Expand All @@ -18,7 +18,7 @@ def serialize(model:, collection_of_attributes:)
)
end

def deserialize(incoming_attributes:, collection_of_attributes:)
def deserialize(incoming_attributes:, collection_of_attributes:, **)
super

Deserialization::ServiceBuilder.build!(self, incoming_attributes, collection_of_attributes)
Expand Down
2 changes: 2 additions & 0 deletions lib/datory/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module Datory
class Base
include Info::DSL
include Context::DSL
include Getters::DSL
include Setters::DSL
include Attributes::DSL
end
end
17 changes: 13 additions & 4 deletions lib/datory/context/callable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def serialize(model) # rubocop:disable Metrics/MethodLength
end
else
context = send(:new, _datory_to_model: false)
model = Datory::Attributes::Serialization::Model.prepare(model)
model = Datory::Attributes::Serialization::Model.prepare(model, collection_of_attributes)
_serialize(context, model)
end
rescue Datory::Service::Exceptions::Input,
Expand All @@ -23,7 +23,7 @@ def serialize(model) # rubocop:disable Metrics/MethodLength
raise Datory::Exceptions::SerializationError.new(message: e.message)
end

def deserialize(data) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
def deserialize(data) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
prepared_data =
if data.is_a?(Datory::Base)
Datory::Attributes::Serialization::Model.to_hash(data)
Expand All @@ -40,6 +40,13 @@ def deserialize(data) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
else
context = send(:new, _datory_to_model: false)

additional_attributes =
collection_of_attributes.external_names.difference(prepared_data.symbolize_keys.keys).to_h do |key|
[key, nil]
end

prepared_data = prepared_data.merge(additional_attributes)

_deserialize(context, **prepared_data)
end
rescue Datory::Service::Exceptions::Input,
Expand Down Expand Up @@ -96,15 +103,17 @@ def _serialize(context, model)
context.send(
:_serialize,
model: model,
collection_of_attributes: collection_of_attributes
collection_of_attributes: collection_of_attributes,
collection_of_setters: collection_of_setters
)
end

def _deserialize(context, **attributes)
context.send(
:_deserialize,
incoming_attributes: attributes.symbolize_keys,
collection_of_attributes: collection_of_attributes
collection_of_attributes: collection_of_attributes,
collection_of_getters: collection_of_getters
)
end

Expand Down
18 changes: 14 additions & 4 deletions lib/datory/context/workspace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ module Context
module Workspace
private

def define_setter(key, value)
self.class.send(:attr_accessor, key)

instance_variable_set(:"@#{key}", value)

self
end

def merge!(attributes)
attributes.each do |key, value|
instance_variable_set(:"@#{key}", value)
Expand All @@ -19,17 +27,19 @@ def keys
instance_variables.map { |instance_variable| instance_variable.to_s.sub(/^@/, "").to_sym }
end

def _serialize(model:, collection_of_attributes:)
def _serialize(model:, collection_of_attributes:, collection_of_setters:)
serialize(
model: model,
collection_of_attributes: collection_of_attributes
collection_of_attributes: collection_of_attributes,
collection_of_setters: collection_of_setters
)
end

def _deserialize(incoming_attributes:, collection_of_attributes:)
def _deserialize(incoming_attributes:, collection_of_attributes:, collection_of_getters:)
deserialize(
incoming_attributes: incoming_attributes,
collection_of_attributes: collection_of_attributes
collection_of_attributes: collection_of_attributes,
collection_of_getters: collection_of_getters
)
end

Expand Down
14 changes: 14 additions & 0 deletions lib/datory/getters/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Datory
module Getters
class Collection
extend Forwardable
def_delegators :@collection, :<<, :each, :merge

def initialize(collection = Set.new)
@collection = collection
end
end
end
end
30 changes: 30 additions & 0 deletions lib/datory/getters/dsl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Datory
module Getters
module DSL
def self.included(base)
base.extend(ClassMethods)
base.include(Workspace)
end

module ClassMethods
def inherited(child)
super

child.send(:collection_of_getters).merge(collection_of_getters)
end

private

def getter(name)
collection_of_getters << Getter.new(name, ->(attributes:) { yield(attributes: attributes) })
end

def collection_of_getters
@collection_of_getters ||= Collection.new
end
end
end
end
end
14 changes: 14 additions & 0 deletions lib/datory/getters/getter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Datory
module Getters
class Getter
attr_reader :name, :block

def initialize(name, block)
@name = name
@block = block
end
end
end
end
17 changes: 17 additions & 0 deletions lib/datory/getters/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

module Datory
module Getters
module Workspace
private

def deserialize(incoming_attributes:, collection_of_attributes:, collection_of_getters:)
super

collection_of_getters.each do |getter|
incoming_attributes.merge!(getter.name => getter.block.call(attributes: incoming_attributes))
end
end
end
end
end
14 changes: 14 additions & 0 deletions lib/datory/setters/collection.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Datory
module Setters
class Collection
extend Forwardable
def_delegators :@collection, :<<, :each, :merge

def initialize(collection = Set.new)
@collection = collection
end
end
end
end
30 changes: 30 additions & 0 deletions lib/datory/setters/dsl.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Datory
module Setters
module DSL
def self.included(base)
base.extend(ClassMethods)
base.include(Workspace)
end

module ClassMethods
def inherited(child)
super

child.send(:collection_of_setters).merge(collection_of_setters)
end

private

def setter(name)
collection_of_setters << Setter.new(name, ->(attributes:) { yield(attributes: attributes) })
end

def collection_of_setters
@collection_of_setters ||= Collection.new
end
end
end
end
end
Loading
Loading