serdee 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d32e12c6af56fcee2b79e0d1c3390410459d5c23
4
+ data.tar.gz: 0e8003cbd25ad282db4749c35119326c3cb23f0e
5
+ SHA512:
6
+ metadata.gz: 97c96e37529521be72bd5ffe824a6f0cc11f07e64e6c838ae7719c32989cfe2b12be649d11b52a4f8144eee88f33dfe8620051d7b8ccff352a5b128d8598f7fe
7
+ data.tar.gz: '0818da033b2801fcf157d2be3f753c5bb61b87385131694c4ae3ba734086d54063bf9a7ac56793a5c68bb9beb7c95809e16255607a8a5ac56f2810db18ad02fb'
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.16.0
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in serdee.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,54 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ serdee (0.1.0)
5
+ activesupport
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (5.2.1)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ coderay (1.1.2)
16
+ concurrent-ruby (1.0.5)
17
+ diff-lcs (1.3)
18
+ i18n (1.1.0)
19
+ concurrent-ruby (~> 1.0)
20
+ method_source (0.9.0)
21
+ minitest (5.11.3)
22
+ pry (0.11.2)
23
+ coderay (~> 1.1.0)
24
+ method_source (~> 0.9.0)
25
+ rake (10.5.0)
26
+ rspec (3.8.0)
27
+ rspec-core (~> 3.8.0)
28
+ rspec-expectations (~> 3.8.0)
29
+ rspec-mocks (~> 3.8.0)
30
+ rspec-core (3.8.0)
31
+ rspec-support (~> 3.8.0)
32
+ rspec-expectations (3.8.1)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.8.0)
35
+ rspec-mocks (3.8.0)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.8.0)
38
+ rspec-support (3.8.0)
39
+ thread_safe (0.3.6)
40
+ tzinfo (1.2.5)
41
+ thread_safe (~> 0.1)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ bundler (~> 1.16)
48
+ pry
49
+ rake (~> 10.0)
50
+ rspec (~> 3.0)
51
+ serdee!
52
+
53
+ BUNDLED WITH
54
+ 1.16.0
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Serdee
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/serdee`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'serdee'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install serdee
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/serdee.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "serdee"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ class Address
3
+ BYTES = {
4
+ address: 22,
5
+ city: 13,
6
+ state: 3,
7
+ country: 2
8
+ }.freeze
9
+ attr_accessor :address, :city, :state, :country
10
+ def initialize(address:, city:, state:, country:)
11
+ @address = address
12
+ @city = city
13
+ @state = state
14
+ @country = country
15
+ end
16
+
17
+ def self.serialize(address)
18
+ return if address.nil?
19
+ BYTES.map do |field, bytes|
20
+ address.send(field)[0...bytes].ljust(bytes, " ")
21
+ end.join
22
+ end
23
+
24
+ def self.deserialize(string)
25
+ return if string.nil?
26
+ string = string.dup
27
+ new(
28
+ BYTES.transform_values { |bytes| string.slice!(0...bytes) }
29
+ )
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ {
2
+ "request":{
3
+ "header":{
4
+ "signature":"BHNUMS",
5
+ "details":{
6
+ "productCategoryCode":"01",
7
+ "specVersion":"04"
8
+ }
9
+ },
10
+ "transaction":{
11
+ "primaryAccountNumber":"9877890000000000",
12
+ "processingCode":"315400",
13
+ "transactionAmount":"000000000000",
14
+ "transmissionDateTime":"131121105414",
15
+ "systemTraceAuditNumber":"000110",
16
+ "localTransactionTime":"105414",
17
+ "localTransactionDate":"131121",
18
+ "merchantCategoryCode":"5411",
19
+ "pointOfServiceEntryMode":"011",
20
+ "acquiringInstitutionIdentifier":"60300000063",
21
+ "retrievalReferenceNumber":"000000002962",
22
+ "merchantTerminalId":"06220 600 ",
23
+ "merchantIdentifier":"60300000063 ",
24
+ "merchantLocation":"BLACKHAWK SIMULATOR PLEASANTON CA US",
25
+ "transactionCurrencyCode":"840",
26
+ "additionalTxnFields":{
27
+ "productId":"07675004390"
28
+ }
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./unified_message"
3
+
4
+ class RequestMessage
5
+ include Serdee::Attributes
6
+ set_key_transform :camel_lower
7
+
8
+ nested :request, UnifiedMessage
9
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+ class ResponseCode
3
+ attr_reader :code, :type, :message
4
+ def initialize(code:, type:, message:)
5
+ @code = code
6
+ @type = type
7
+ @message = message
8
+ end
9
+
10
+ def approved?
11
+ type == :approved
12
+ end
13
+
14
+ def soft_declined?
15
+ type == :soft_declined
16
+ end
17
+
18
+ def hard_declined?
19
+ type == :hard_declined
20
+ end
21
+
22
+ def self.find(code)
23
+ response = CODES.fetch(code)
24
+ new(
25
+ code: code,
26
+ type: response[0],
27
+ message: response[1]
28
+ )
29
+ end
30
+
31
+ CODES = {
32
+ "00" => [:approved, "Approved – balance available"],
33
+ "01" => [:approved, "Approved – balance unavailable"],
34
+ "03" => [:approved, "Approved – balance unavailable on external account number"],
35
+ "74" => [:soft_declined, "Unable to route / System Error"],
36
+ "15" => [:soft_declined, "Time Out occurred- Auth Server not available /responding"],
37
+ "02" => [:hard_declined, "Refer to card issuer"],
38
+ "04" => [:hard_declined, "Already Redeemed"],
39
+ "05" => [:hard_declined, "Error account problem"],
40
+ "06" => [:hard_declined, "Invalid expiration date"],
41
+ "07" => [:hard_declined, "Unable to process"],
42
+ "08" => [:hard_declined, "Card not found"],
43
+ "12" => [:hard_declined, "Invalid transaction"],
44
+ "13" => [:hard_declined, "Invalid amount"],
45
+ "14" => [:hard_declined, "Invalid Product"],
46
+ "16" => [:hard_declined, "Invalid status change"],
47
+ "17" => [:hard_declined, "Invalid merchant"],
48
+ "18" => [:hard_declined, "Invalid Phone Number"],
49
+ "20" => [:hard_declined, "Invalid Pin"],
50
+ "21" => [:hard_declined, "Card already active"],
51
+ "22" => [:hard_declined, "Card Already Associated"],
52
+ "30" => [:hard_declined, "Bad track2 – format error"],
53
+ "33" => [:hard_declined, "Expired card"],
54
+ "34" => [:hard_declined, "Already reversed"],
55
+ "35" => [:hard_declined, "Already voided"],
56
+ "36" => [:hard_declined, "Restricted card"],
57
+ "37" => [:hard_declined, "Restricted External Account"],
58
+ "38" => [:hard_declined, "Restricted Merchant"],
59
+ "41" => [:hard_declined, "Lost card"],
60
+ "42" => [:hard_declined, "Lost External Account"],
61
+ "43" => [:hard_declined, "Stolen card"],
62
+ "44" => [:hard_declined, "Stolen External Account"],
63
+ "51" => [:hard_declined, "Insufficient funds"],
64
+ "54" => [:hard_declined, "Expired External Account"],
65
+ "55" => [:hard_declined, "Max recharge reached"],
66
+ "56" => [:hard_declined, "Advance less amount / enter lesser amount"],
67
+ "58" => [:hard_declined, "Request not permitted by merchant location"],
68
+ "59" => [:hard_declined, "Request not permitted by processor"],
69
+ "61" => [:hard_declined, "Exceeds withdrawal amt / over limit"],
70
+ "62" => [:hard_declined, "Exceeds financial limit"],
71
+ "65" => [:hard_declined, "Exceeds withdrawal frequency limit"],
72
+ "66" => [:hard_declined, "Exceeds transaction count limit"],
73
+ "69" => [:hard_declined, "Format error –bad data"],
74
+ "71" => [:hard_declined, "Invalid External Account number"],
75
+ "94" => [:hard_declined, "Duplicate transaction"],
76
+ "95" => [:hard_declined, "Cannot Reverse the Original Transaction"],
77
+ "99" => [:hard_declined, "General decline"],
78
+ }.freeze
79
+ end
@@ -0,0 +1,36 @@
1
+ {
2
+ "response":{
3
+ "header":{
4
+ "signature":"BHNUMS",
5
+ "details":{
6
+ "productCategoryCode":"01",
7
+ "statusCode":"00",
8
+ "specVersion":"04"
9
+ }
10
+ },
11
+ "transaction":{
12
+ "primaryAccountNumber":"9877890000000000",
13
+ "processingCode":"315400",
14
+ "transactionAmount":"000000000000",
15
+ "transmissionDateTime":"131121105414",
16
+ "systemTraceAuditNumber":"000110",
17
+ "localTransactionTime":"105414",
18
+ "localTransactionDate":"131121",
19
+ "merchantCategoryCode":"5411",
20
+ "pointOfServiceEntryMode":"011",
21
+ "acquiringInstitutionIdentifier":"60300000063",
22
+ "authidentificationResponse":"123456",
23
+ "responseCode":"00",
24
+ "retrievalReferenceNumber":"000000002962",
25
+ "merchantTerminalId":"06220 600 ",
26
+ "merchantIdentifier":"60300000063 ",
27
+ "transactionCurrencyCode":"840",
28
+ "additionalTxnFields":{
29
+ "productId":"07675004390",
30
+ "balanceAmount":"C000000002500",
31
+ "transactionUniqueId": "0JPKA8FKHT2H011784WA0524PM",
32
+ "correlatedTransactionUniqueId": "0JPKA8FKHT2H011784WA0524PM"
33
+ }
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./unified_message"
3
+ require_relative "./response_code"
4
+ class ResponseMessage
5
+ include Serdee::Attributes
6
+ set_key_transform :camel_lower
7
+
8
+ attr_accessor :request_id
9
+
10
+ nested :response, UnifiedMessage
11
+
12
+ def parsed_message?
13
+ status_code == "00" if status_code
14
+ end
15
+
16
+ def status
17
+ return unless response_code
18
+ @status ||= ResponseCode.find(response_code)
19
+ end
20
+
21
+ def approved?
22
+ status&.approved?
23
+ end
24
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+ require_relative "./address"
3
+ require_relative "./response_code"
4
+
5
+ class UnifiedMessage
6
+ include Serdee::Attributes
7
+ set_key_transform :camel_lower
8
+
9
+ PROCESSING_CODES = {
10
+ balance_inquiry: "315400",
11
+ redemption: "615400"
12
+ }.freeze
13
+
14
+ nested :header do
15
+ attribute :signature, default: "BHNUMS"
16
+ nested :details do
17
+ attribute :product_category_code, default: "01"
18
+ attribute :spec_version, default: "43"
19
+ attribute :status_code
20
+ end
21
+ end
22
+
23
+ nested :transaction do
24
+ attribute :local_transaction_at do
25
+ insert do |time, hash|
26
+ if time
27
+ hash[:local_transaction_time] = time.strftime("%H%M%S")
28
+ hash[:local_transaction_date] = time.strftime("%y%m%d")
29
+ end
30
+ end
31
+
32
+ extract do |data|
33
+ if data[:local_transaction_date] && data[:local_transaction_time]
34
+ time_string = "#{data[:local_transaction_date]}-#{data[:local_transaction_time]}"
35
+ DateTime.strptime(time_string, "%y%m%d-%H%M%S")
36
+ end
37
+ end
38
+ end
39
+ attribute :retrieval_reference_number do
40
+ serialize { |int| format("%012d", int) }
41
+ deserialize { |string| string&.to_i }
42
+ end
43
+ attribute :system_trace_audit_number do
44
+ serialize { |int| format("%06d", int) }
45
+ deserialize { |string| string&.to_i }
46
+ end
47
+ attribute :transaction_amount do
48
+ serialize { |int| format("%012d", int) }
49
+ deserialize { |string| string&.to_i }
50
+ end
51
+ attribute :transmission_date_time do
52
+ serialize { |time| time&.strftime("%y%m%d%H%M%S") }
53
+ deserialize { |time_string| DateTime.strptime(time_string, "%y%m%d%H%M%S") if time_string }
54
+ end
55
+ attribute :merchant_identifier do
56
+ serialize { |id| id&.ljust(15, " ") }
57
+ deserialize { |id| id&.strip }
58
+ end
59
+ attribute :action, as: :processing_code do
60
+ serialize { |action| PROCESSING_CODES.fetch(action) }
61
+ deserialize { |code| PROCESSING_CODES.key(code) }
62
+ end
63
+ attribute :merchant_location, serializer: Address
64
+
65
+ attribute :authidentification_response
66
+ attribute :acquiring_institution_identifier
67
+ attribute :merchant_category_code
68
+ attribute :merchant_terminal_id
69
+ attribute :point_of_service_entry_mode
70
+ attribute :primary_account_number
71
+ attribute :response_code
72
+ attribute :transaction_currency_code
73
+
74
+ nested :additional_txn_fields do
75
+ attribute :balance_amount do
76
+ serialize do |int|
77
+ return if int.nil?
78
+ (int >= 0 ? "C" : "D") + int.abs.to_s.rjust(12, "0")
79
+ end
80
+ deserialize do |string|
81
+ return if string.nil?
82
+ int = string[1..-1].to_i
83
+ return -int if string[0] == "D"
84
+ int
85
+ end
86
+ end
87
+ attribute :correlated_transaction_unique_id
88
+ attribute :product_id
89
+ attribute :transaction_unique_id
90
+ attribute :redemption_pin do
91
+ serialize { |pin| pin&.ljust(16, " ") }
92
+ deserialize { |pin| pin&.strip }
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+ module Serdee
3
+ class Attribute
4
+ attr_reader :key, :default
5
+ attr_writer :as
6
+ attr_accessor :default, :allow_blank, :serializer, :optional
7
+
8
+ def initialize(key, **options, &block)
9
+ @key = key
10
+ { allow_blank: false }.merge(options).each do |option, setting|
11
+ config.public_send(option, setting)
12
+ end
13
+ config.instance_eval(&block) if block_given?
14
+ end
15
+
16
+ def config
17
+ @config ||= Config.new(self)
18
+ end
19
+
20
+ def as
21
+ @as || key
22
+ end
23
+
24
+ def default=(val)
25
+ @optional = true
26
+ @default = val
27
+ end
28
+
29
+ def insert(value, hash)
30
+ new_value = serialize(value)
31
+ hash[as] = new_value if new_value.present? || allow_blank
32
+ end
33
+
34
+ def insert_to(obj, hash)
35
+ insert(obj.send(key), hash)
36
+ hash
37
+ end
38
+
39
+ def extract_to(data, obj)
40
+ obj.send("#{key}=", extract(data))
41
+ obj
42
+ end
43
+
44
+ def extract(hash)
45
+ deserialize(hash[as])
46
+ end
47
+
48
+ def serialize(value)
49
+ value
50
+ end
51
+
52
+ def deserialize(value)
53
+ value
54
+ end
55
+
56
+ class Config
57
+ attr_reader :attribute
58
+ def initialize(attribute)
59
+ @attribute = attribute
60
+ end
61
+
62
+ def serializer(obj)
63
+ return unless obj
64
+
65
+ attribute.serializer = obj
66
+ serialize { |value| obj.serialize(value) }
67
+ deserialize { |value| obj.deserialize(value) }
68
+ end
69
+
70
+ [
71
+ :optional,
72
+ :default,
73
+ :allow_blank,
74
+ :as
75
+ ].each do |key|
76
+ define_method(key) do |value|
77
+ attribute.send("#{key}=", value)
78
+ end
79
+ end
80
+
81
+ [
82
+ :extract_to,
83
+ :insert_to,
84
+ :extract,
85
+ :insert,
86
+ :serialize,
87
+ :deserialize
88
+ ].each do |key|
89
+ expected_arg_size = Attribute.instance_method(key).parameters.size
90
+ define_method(key) do |&block|
91
+ if block.parameters.size > expected_arg_size || block.parameters.any? { |type, _key| type == :keyreq }
92
+ raise ArgumentError,
93
+ "wrong number of arguments defined for ##{key} (given #{block.parameters}, expected #{args})"
94
+ end
95
+ attribute.singleton_class.send(:define_method, key, &block)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+ require "active_support/core_ext/hash"
3
+
4
+ module Serdee
5
+ module Attributes
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ attr_accessor :deserialized_from
11
+
12
+ def initialize(**values)
13
+ self.class.attributes.each do |key, attribute|
14
+ if !attribute.optional && !values.key?(key)
15
+ raise ArgumentError, "#{key} is required parameter"
16
+ end
17
+
18
+ if values.key?(key)
19
+ send("#{key}=", values[key])
20
+ elsif attribute.default
21
+ send("#{key}=", attribute.default)
22
+ end
23
+ end
24
+ end
25
+
26
+ def attributes
27
+ self.class.attributes.keys.each_with_object({}) do |key, hash|
28
+ value = send(key)
29
+ hash[key] = value if value
30
+ end
31
+ end
32
+
33
+ def as_json
34
+ self.class.insert_to(self, {}).deep_transform_keys! do |key|
35
+ if self.class.key_transform
36
+ self.class.key_transform.call(key.to_s)
37
+ else
38
+ key.to_s
39
+ end
40
+ end
41
+ end
42
+
43
+ def to_json
44
+ as_json.to_json
45
+ end
46
+
47
+ module ClassMethods
48
+ def attributes
49
+ @attributes ||= {}
50
+ end
51
+
52
+ def serializers
53
+ @serializers ||= {}
54
+ end
55
+
56
+ def set_key_transform(transform_name = nil, &block)
57
+ if transform_name
58
+ mapping = {
59
+ camel: :camelize.to_proc,
60
+ camel_lower: ->(key) { key.camelize(:lower) },
61
+ dash: :dasherize.to_proc,
62
+ underscore: :underscore.to_proc
63
+ }
64
+
65
+ @key_transform = mapping[transform_name.to_sym]
66
+ elsif block
67
+ @key_transform = block
68
+ else
69
+ raise ArgumentError, "must supply at least transform_name or block"
70
+ end
71
+ end
72
+
73
+ def key_transform
74
+ @key_transform || Serdee.default_key_transform
75
+ end
76
+
77
+ def attributes_class
78
+ self
79
+ end
80
+
81
+ def attribute(key, *args, &block)
82
+ attributes_class.attributes[key] = serializers[key] =
83
+ Attribute.new(key, *args, &block)
84
+
85
+ attributes_class.send(:attr_accessor, key)
86
+ end
87
+
88
+ def nested(key, nested_class = nil, &block)
89
+ serializers[key] = Nested.new(
90
+ attributes_class,
91
+ key,
92
+ nested_class&.serializers,
93
+ &block
94
+ )
95
+
96
+ return unless nested_class
97
+
98
+ attributes_class.attributes.merge!(nested_class.attributes)
99
+ attributes_class.send(:attr_accessor, *nested_class.attributes.keys)
100
+ end
101
+
102
+ def from_json(json)
103
+ of_json(JSON.parse(json))
104
+ end
105
+
106
+ def of_json(json)
107
+ allocate.tap do |obj|
108
+ data = json.deep_transform_keys do |key|
109
+ key.underscore.to_sym
110
+ end
111
+ extract_to(data, obj)
112
+ obj.deserialized_from = json
113
+ end
114
+ end
115
+
116
+ def extract_to(data, obj)
117
+ return if obj.nil?
118
+ serializers.each do |_key, attribute|
119
+ attribute.extract_to(data, obj)
120
+ end
121
+ obj
122
+ end
123
+
124
+ def insert_to(obj, data)
125
+ serializers.each do |_key, attribute|
126
+ attribute.insert_to(obj, data)
127
+ end
128
+ data
129
+ end
130
+ end
131
+
132
+ class Nested
133
+ include Attributes::ClassMethods
134
+
135
+ attr_reader :key, :attributes_class
136
+ def initialize(attributes_class, key, serializers, &block)
137
+ @attributes_class = attributes_class
138
+ @key = key
139
+ @serializers = serializers
140
+ instance_eval(&block) if block_given?
141
+ end
142
+
143
+ def extract_to(data, obj)
144
+ return if data.nil? || data[key].nil?
145
+ super(data[key], obj)
146
+ end
147
+
148
+ def insert_to(obj, data)
149
+ data[key] = {}
150
+ super(obj, data[key])
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,3 @@
1
+ module Serdee
2
+ VERSION = "0.1.0"
3
+ end
data/lib/serdee.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "json"
2
+ require "serdee/version"
3
+ require "serdee/attribute"
4
+ require "serdee/attributes"
5
+
6
+ module Serdee
7
+ class << self
8
+ attr_accessor :default_key_transform
9
+ end
10
+ end
data/serdee.gemspec ADDED
@@ -0,0 +1,30 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "serdee/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "serdee"
8
+ spec.version = Serdee::VERSION
9
+ spec.authors = ["Ryan Ong"]
10
+ spec.email = ["ryanong@gmail.com"]
11
+
12
+ spec.summary = %q{Serdee is a serialization/deserialization library for mostly json}
13
+ spec.description = %q{Serdee is a highly customizable serialization and deserialization library that is strict by default.}
14
+ spec.homepage = "https://github.com/ryanong/serdee"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+
24
+ spec.add_dependency "activesupport"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.16"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "pry"
30
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: serdee
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Ong
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-09-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Serdee is a highly customizable serialization and deserialization library
84
+ that is strict by default.
85
+ email:
86
+ - ryanong@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - README.md
97
+ - Rakefile
98
+ - bin/console
99
+ - bin/setup
100
+ - examples/address.rb
101
+ - examples/request_message.json
102
+ - examples/request_message.rb
103
+ - examples/response_code.rb
104
+ - examples/response_message.json
105
+ - examples/response_message.rb
106
+ - examples/unified_message.rb
107
+ - lib/serdee.rb
108
+ - lib/serdee/attribute.rb
109
+ - lib/serdee/attributes.rb
110
+ - lib/serdee/version.rb
111
+ - serdee.gemspec
112
+ homepage: https://github.com/ryanong/serdee
113
+ licenses: []
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.6.11
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Serdee is a serialization/deserialization library for mostly json
135
+ test_files: []