api_mapper 0.2.0 → 0.3.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
  SHA1:
3
- metadata.gz: 2498ac8e2869d4236466e5ba3dd02c170a758ae5
4
- data.tar.gz: e077a20464c4e2ba93ed8280e00db963ac2daab5
3
+ metadata.gz: 17285ac6fa2b8436cbe549eda333919eb19ce74c
4
+ data.tar.gz: f772eaf357ec8e797dbfd4fb6d34d1671714309a
5
5
  SHA512:
6
- metadata.gz: e0e34598d340dcf24922ae956dda3dcbf03899a59d41255db29e65d912789b382d2b056147eed935826ac24383ff9c24d5202c69ea3e34d4857bf7eae456b140
7
- data.tar.gz: 40b304f67644549841318411f64121c9f456f79bfe6b489a119937e6829a94fade290dd425a1b3308fd5b7baf9b8923750381ee77044ada1b0f1f6707b25ca70
6
+ metadata.gz: 558493576f5d5628d2bb0092609a14a579cd8b2f481a1618a6928e3e463c366a5c97765422e57935b8f196a83f1da8d1544c96a605260e31f2f4641f849d1b20
7
+ data.tar.gz: 0ce554a9d568dbb2266a067fea4b61a6e00f41608e53b82848ca50b965cedacbcaf4748fc58efa464fac4198c56298794bc740235aa04d82cd3ebe081571fcdc
@@ -0,0 +1,40 @@
1
+ Metrics/AbcSize:
2
+ Max: 18
3
+ Exclude:
4
+ - "test/**/*_test.rb"
5
+
6
+ Metrics/LineLength:
7
+ Max: 120
8
+
9
+ Metrics/MethodLength:
10
+ Max: 11
11
+ Exclude:
12
+ - "test/**/*_test.rb"
13
+
14
+ Style/Documentation:
15
+ Enabled: false
16
+
17
+ Style/NumericLiterals:
18
+ Enabled: false
19
+
20
+ Style/StringLiterals:
21
+ EnforcedStyle: double_quotes
22
+
23
+ Style/StringLiteralsInInterpolation:
24
+ EnforcedStyle: double_quotes
25
+
26
+ Style/TrivialAccessors:
27
+ AllowDSLWriters: true
28
+
29
+ Style/MethodCalledOnDoEndBlock:
30
+ Enabled: true
31
+
32
+ Style/Send:
33
+ Enabled: true
34
+
35
+ Style/CollectionMethods:
36
+ Enabled: true
37
+
38
+ Style/FileName:
39
+ Enabled: false
40
+
@@ -1,12 +1,12 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9
4
- - 2.0
5
3
  - 2.1
6
4
  - 2.2
7
- - jruby
8
5
  - rbx
9
6
  - ruby-head
10
7
  before_install: gem install bundler -v 1.10.2
11
8
  env:
12
9
  - CODECLIMATE_REPO_TOKEN=9be4b54e9c656f7ddf1e62e80ca02263014d439df7ccceef480369d133f05ffb
10
+ addons:
11
+ code_climate:
12
+ repo_token: 9be4b54e9c656f7ddf1e62e80ca02263014d439df7ccceef480369d133f05ffb
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in api_mapper.gemspec
4
4
  gemspec
5
5
 
6
- gem "codeclimate-test-reporter", group: :test, require: false
6
+ gem "codeclimate-test-reporter", group: :test, require: false
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  # ApiMapper
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/api_mapper.svg)](http://badge.fury.io/rb/api_mapper)
3
4
  [![Build Status](https://travis-ci.org/martinciu/api_mapper.svg?branch=master)](https://travis-ci.org/martinciu/api_mapper)
4
5
  [![Code Climate](https://codeclimate.com/github/martinciu/api_mapper/badges/gpa.svg)](https://codeclimate.com/github/martinciu/api_mapper)
5
6
  [![Test Coverage](https://codeclimate.com/github/martinciu/api_mapper/badges/coverage.svg)](https://codeclimate.com/github/martinciu/api_mapper/coverage)
6
7
  [![Dependency Status](https://gemnasium.com/martinciu/api_mapper.svg)](https://gemnasium.com/martinciu/api_mapper)
8
+ [![Inline docs](http://inch-ci.org/github/martinciu/api_mapper.svg?branch=master)](http://inch-ci.org/github/martinciu/api_mapper)
7
9
 
8
10
  ApiMapper converts API resources into ruby objects
9
11
 
@@ -28,11 +30,22 @@ Or install it yourself as:
28
30
  ## Usage
29
31
 
30
32
  ```ruby
33
+
34
+ # Github example
35
+
31
36
  class User
32
- include Virtus.model
33
- attribute :id, Integer
34
- attribute :login
35
- attribute :hireable, Boolean
37
+ attr_reader :id, :login
38
+ def initialize(id, login)
39
+ @id, @login = id, login
40
+ end
41
+ end
42
+
43
+ # simple mapper
44
+ # Mapper have to provide `call` method that accepts array as an argument
45
+ class UserMapper
46
+ def call(origin)
47
+ origin.map { |attributes| User.new(attributes["id"], attributes["login"]) }
48
+ end
36
49
  end
37
50
 
38
51
  class Repository
@@ -43,21 +56,24 @@ class Repository
43
56
  attribute :owner, User
44
57
  end
45
58
 
46
- class UserMapper < ApiMapper::Mapper
47
- attributes :id, :login, :hireable
48
- entity User
49
- end
50
-
51
- class RepositoriesMapper < ApiMapper::ArrayMapper
52
- attributes :id, :name, :full_name
53
- relationship :owner, UserMapper
54
- entity Repository
59
+ # Example of complex mapper using faceter gem (https://github.com/nepalez/faceter)
60
+ class RepositoriesMapper < Faceter::Mapper
61
+ list do
62
+ symbolize_keys
63
+ create :owner, from: [:owner] do |owner|
64
+ UserMapper.new.call(owner)
65
+ end
66
+ wrap to: :attributes, only: [:id, :name, :full_name, :owner]
67
+ create from: [:attributes] do |attributes|
68
+ Repository.new(attributes)
69
+ end
70
+ end
55
71
  end
56
72
 
57
73
  class Router < ApiMapper::Router
58
- get "user", UserMapper
59
- patch "user", UserMapper
60
- get "repositories", RepositoriesMapper
74
+ get "user", UserMapper.new
75
+ patch "user", UserMapper.new
76
+ get "repositories", RepositoryMapper.build
61
77
  end
62
78
 
63
79
  # client setup
@@ -84,6 +100,52 @@ repository.name # grit
84
100
  repository.full_name # mojombo/grit
85
101
  repository.user.id # 1
86
102
  repository.user.login # mojombo
103
+
104
+ # Moves app example (complex mapper)
105
+
106
+ class Profile
107
+ include Virtus.model
108
+
109
+ attribute :id, Integer
110
+ attribute :created_at, Date
111
+ attribute :locale, String
112
+ attribute :metric, Boolean
113
+ end
114
+
115
+ # {
116
+ # "userId": 23138311640030064,
117
+ # "profile": {
118
+ # "firstDate": "20121211",
119
+ # "currentTimeZone": {
120
+ # "id": "Europe/Helsinki",
121
+ # "offset": 10800
122
+ # },
123
+ # "localization": {
124
+ # "language": "en",
125
+ # "locale": "fi_FI",
126
+ # "firstWeekDay": 2,
127
+ # "metric": true
128
+ # },
129
+ # "caloriesAvailable": true,
130
+ # "platform": "ios"
131
+ # }
132
+ # }
133
+
134
+ # Example of complex mapper using rom-mapper gem (https://github.com/rom-rb/rom-mapper)
135
+ class ProfileMapper < ROM::Mapper
136
+ reject_keys true
137
+ attribute :id, from: "userId"
138
+ unwrap "profile" do
139
+ attribute :created_at, from: "firstDate"
140
+ attribute :metric
141
+ attribute :locale
142
+ unwrap "localization" do
143
+ attribute :metric, from: "metric"
144
+ attribute :locale, from: "locale"
145
+ end
146
+ end
147
+ model Profile
148
+ end
87
149
  ```
88
150
 
89
151
  ## Development
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require "rake/testtask"
4
4
  Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test"
6
6
  t.libs << "lib"
7
- t.test_files = FileList['test/**/*_test.rb']
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
8
  end
9
9
 
10
- task :default => :test
10
+ task default: :test
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
2
+ lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'api_mapper/version'
4
+ require "api_mapper/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "api_mapper"
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Marcin Ciunelis"]
10
10
  spec.email = ["marcin.ciunelis@gmail.com"]
11
11
 
12
- spec.summary = %q{api_mapper converts API resources in to ruby objects}
13
- spec.description = %q{}
12
+ spec.summary = "api_mapper converts API resources in to ruby objects"
13
+ spec.description = ""
14
14
  # spec.homepage = "TODO: Put your gem's website or public repo URL here."
15
15
  spec.license = "MIT"
16
16
 
@@ -19,18 +19,18 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
+ spec.required_ruby_version = ">= 2.1"
23
+
22
24
  spec.add_dependency "faraday", "~> 0.9.1"
23
25
  spec.add_dependency "json", "~> 1.8.3"
24
26
  spec.add_dependency "addressable", "~> 2.3.6"
25
- spec.add_dependency "transproc", "~> 0.3.1"
26
-
27
- # test mappers dependencies
28
- spec.add_dependency "anima", "~> 0.2.0"
29
- spec.add_dependency "virtus", "~> 1.0.5"
30
27
 
31
28
  spec.add_development_dependency "bundler", "~> 1.10"
32
29
  spec.add_development_dependency "rake", "~> 10.0"
33
30
  spec.add_development_dependency "minitest", "~> 5.8.0"
34
31
  spec.add_development_dependency "vcr", "~> 2.9.3"
35
32
  spec.add_development_dependency "webmock", "~> 1.21.0"
33
+ spec.add_development_dependency "virtus", "~> 1.0.5"
34
+ spec.add_development_dependency "rubocop", "~> 0.33"
35
+ spec.add_development_dependency "rom-mapper", "~> 0.2.0"
36
36
  end
@@ -1,17 +1,13 @@
1
- require "anima"
2
1
  require "faraday"
3
2
  require "json"
4
- require "transproc/all"
5
3
  require "addressable/template"
6
- require "virtus"
7
4
 
8
5
  require "api_mapper/router"
9
6
  require "api_mapper/client"
10
- require "api_mapper/mapper"
11
- require "api_mapper/functions"
12
7
 
13
8
  require "api_mapper/version"
14
9
 
10
+ # ApiMapper converts API resources into ruby objects
11
+ #
15
12
  module ApiMapper
16
- # Your code goes here...
17
13
  end
@@ -1,44 +1,109 @@
1
1
  module ApiMapper
2
+ # API client class
3
+ #
4
+ # Provides methods to access API endpoints
5
+ # @example
6
+ # client = ApiMapper::Client.new('http://api.example.com')
7
+ # client.authorization("token super_secret_token")
8
+ # user = client.get("user")
9
+ # user.login = 'Incognito'
10
+ # incognito_user = client.patch("user", user)
11
+ #
12
+ # @attr_writer (ApiMapper::Router) router router used for processing requests
2
13
  class Client
3
-
4
14
  attr_writer :router
5
15
 
16
+ # A new instance of ApiMapper::Client
17
+ #
18
+ # @param (String) base_url base URL of all API endpoints
19
+ # @return (ApiMapper::Client)
6
20
  def initialize(base_url)
7
21
  @base_url = base_url
8
22
  @router = Router.new
9
23
  end
10
24
 
25
+ # Make HTTP GET request
26
+ #
27
+ # @example
28
+ # client.get('users')
29
+ #
30
+ # @param (String) path request path
31
+ #
32
+ # @return [Array, Object] mapped API response
11
33
  def get(path)
12
- mapper(:get, path).call(response(:get, path).body)
34
+ response = response(:get, path)
35
+ mapper = mapper(:get, path)
36
+
37
+ map_response(mapper, response)
13
38
  end
14
39
 
15
- def patch(path, body)
16
- mapper(:patch, path).call(response(:patch, path, body).body)
40
+ # Make HTTP PATCH request
41
+ #
42
+ # @example
43
+ # client.patch('users', user)
44
+ #
45
+ # @param (String) path request path
46
+ # @param (Object) payload request payload
47
+ #
48
+ # @return [Array, Object] mapped API response
49
+ def patch(path, payload)
50
+ mapper = mapper(:patch, path)
51
+ response = response(:patch, path, payload)
52
+
53
+ map_response(mapper, response)
17
54
  end
18
55
 
19
- def post(path, body)
20
- mapper(:post, path).call(response(:post, path, body).body)
56
+ # Make HTTP POST request
57
+ #
58
+ # @example
59
+ # client.post('users', user)
60
+ #
61
+ # @param (String) path request path
62
+ # @param (Object) payload request payload
63
+ #
64
+ # @return [Array, Object] mapped API response
65
+ def post(path, payload)
66
+ mapper = mapper(:post, path)
67
+ response = response(:post, path, payload)
68
+
69
+ map_response(mapper, response)
21
70
  end
22
71
 
72
+ # Authorize client using `Authorization` HTTP header
73
+ #
74
+ # @example
75
+ # client.authorize("Bearer secret_token")
76
+ #
77
+ # @param (String) authorization authorization header
78
+ # @return (String) authorization header
23
79
  def authorization(authorization)
24
80
  @authorization = authorization
25
81
  end
26
82
 
27
83
  private
28
84
 
85
+ def map_response(mapper, response)
86
+ body = response.body
87
+ if body.is_a? Hash
88
+ mapper.call([body])[0]
89
+ else
90
+ mapper.call(body)
91
+ end
92
+ end
93
+
29
94
  def mapper(method, path)
30
- @router.resolve(method, path).mapper.new
95
+ @router.resolve(method, path).mapper
31
96
  end
32
97
 
33
98
  def response(method, path, body = nil)
34
- Response.new(connection.send(method, path, Serializer.new(body).call))
99
+ Response.new(connection.__send__(method, path, Serializer.new(body).call))
35
100
  end
36
101
 
37
102
  def connection
38
103
  @connection ||= Faraday.new(url: @base_url) do |conn|
39
104
  conn.adapter :net_http
40
- conn.headers["Content-Type"] = 'application/json'
41
- conn.headers["Accept"] = 'application/json'
105
+ conn.headers["Content-Type"] = "application/json"
106
+ conn.headers["Accept"] = "application/json"
42
107
  conn.headers["Authorization"] = @authorization if @authorization
43
108
  conn.headers["X-Client"] = "ApiMapper-v#{ApiMapper::VERSION}"
44
109
  end
@@ -61,16 +126,19 @@ module ApiMapper
61
126
  end
62
127
 
63
128
  def call
64
- attributes.inject({}) do |response, (key, value)|
65
- response.merge(key => value)
66
- end.to_json if @model
129
+ serialize.to_json if @model
67
130
  end
68
131
 
69
132
  private
70
133
 
134
+ def serialize
135
+ attributes.reduce({}) do |response, (key, value)|
136
+ response.merge(key => value)
137
+ end
138
+ end
139
+
71
140
  def attributes
72
- @model.attributes.select { |_, value| value != nil }
141
+ @model.attributes.select { |_, value| !value.nil? }
73
142
  end
74
143
  end
75
-
76
- end
144
+ end
@@ -1,3 +1,3 @@
1
1
  module ApiMapper
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcin Ciunelis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-08-10 00:00:00.000000000 Z
11
+ date: 2015-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -53,117 +53,117 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.3.6
55
55
  - !ruby/object:Gem::Dependency
56
- name: transproc
56
+ name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.3.1
62
- type: :runtime
61
+ version: '1.10'
62
+ type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.3.1
68
+ version: '1.10'
69
69
  - !ruby/object:Gem::Dependency
70
- name: anima
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.2.0
76
- type: :runtime
75
+ version: '10.0'
76
+ type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.2.0
82
+ version: '10.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: virtus
84
+ name: minitest
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 1.0.5
90
- type: :runtime
89
+ version: 5.8.0
90
+ type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 1.0.5
96
+ version: 5.8.0
97
97
  - !ruby/object:Gem::Dependency
98
- name: bundler
98
+ name: vcr
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '1.10'
103
+ version: 2.9.3
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '1.10'
110
+ version: 2.9.3
111
111
  - !ruby/object:Gem::Dependency
112
- name: rake
112
+ name: webmock
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '10.0'
117
+ version: 1.21.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '10.0'
124
+ version: 1.21.0
125
125
  - !ruby/object:Gem::Dependency
126
- name: minitest
126
+ name: virtus
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 5.8.0
131
+ version: 1.0.5
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 5.8.0
138
+ version: 1.0.5
139
139
  - !ruby/object:Gem::Dependency
140
- name: vcr
140
+ name: rubocop
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 2.9.3
145
+ version: '0.33'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 2.9.3
152
+ version: '0.33'
153
153
  - !ruby/object:Gem::Dependency
154
- name: webmock
154
+ name: rom-mapper
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - "~>"
158
158
  - !ruby/object:Gem::Version
159
- version: 1.21.0
159
+ version: 0.2.0
160
160
  type: :development
161
161
  prerelease: false
162
162
  version_requirements: !ruby/object:Gem::Requirement
163
163
  requirements:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
- version: 1.21.0
166
+ version: 0.2.0
167
167
  description: ''
168
168
  email:
169
169
  - marcin.ciunelis@gmail.com
@@ -172,6 +172,7 @@ extensions: []
172
172
  extra_rdoc_files: []
173
173
  files:
174
174
  - ".gitignore"
175
+ - ".rubocop.yml"
175
176
  - ".travis.yml"
176
177
  - CODE_OF_CONDUCT.md
177
178
  - Gemfile
@@ -183,23 +184,8 @@ files:
183
184
  - bin/setup
184
185
  - lib/api_mapper.rb
185
186
  - lib/api_mapper/client.rb
186
- - lib/api_mapper/functions.rb
187
- - lib/api_mapper/mapper.rb
188
187
  - lib/api_mapper/router.rb
189
188
  - lib/api_mapper/version.rb
190
- - lib/github_mapper.rb
191
- - lib/github_mapper/entities/emoji.rb
192
- - lib/github_mapper/entities/issue.rb
193
- - lib/github_mapper/entities/profile.rb
194
- - lib/github_mapper/entities/repository.rb
195
- - lib/github_mapper/entities/user.rb
196
- - lib/github_mapper/mappers/emoji_mapper.rb
197
- - lib/github_mapper/mappers/issue_mapper.rb
198
- - lib/github_mapper/mappers/profile_mapper.rb
199
- - lib/github_mapper/mappers/repositories_mapper.rb
200
- - lib/github_mapper/mappers/repository_mapper.rb
201
- - lib/github_mapper/mappers/user_mapper.rb
202
- - lib/github_mapper/router.rb
203
189
  homepage:
204
190
  licenses:
205
191
  - MIT
@@ -212,7 +198,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
212
198
  requirements:
213
199
  - - ">="
214
200
  - !ruby/object:Gem::Version
215
- version: '0'
201
+ version: '2.1'
216
202
  required_rubygems_version: !ruby/object:Gem::Requirement
217
203
  requirements:
218
204
  - - ">="
@@ -1,30 +0,0 @@
1
- module ApiMapper
2
- module Functions
3
- extend Transproc::Registry
4
-
5
- module HashTransformations
6
- def self.structure(hash, key_name, value_name)
7
- hash.map { |key, value| { key_name => key, value_name => value } }
8
- end
9
- end
10
-
11
- module Factory
12
- def self.factory(attributes, klass)
13
- klass.new(attributes)
14
- end
15
- end
16
-
17
- module Mapping
18
- def self.mapping(hash, mapper)
19
- mapper.new.call(hash)
20
- end
21
- end
22
-
23
- import Transproc::HashTransformations
24
- import Transproc::ArrayTransformations
25
- import Transproc::Conditional
26
- import HashTransformations
27
- import Factory
28
- import Mapping
29
- end
30
- end
@@ -1,77 +0,0 @@
1
- module ApiMapper
2
- class Mapper
3
-
4
- def call(origin)
5
- self.class.transformation.call(origin)
6
- end
7
-
8
- class << self
9
- def attributes(*attributes)
10
- @attributes ||= Array(@attributes) + attributes
11
- end
12
-
13
- def entity(klass)
14
- @entity = klass
15
- end
16
-
17
- def relationship(name, mapper = nil)
18
- @relationships ||= []
19
- @relationships << Relationship.new(name, mapper)
20
- end
21
-
22
- def transformation
23
- mapping >> factory
24
- end
25
-
26
- private
27
-
28
- def all_attributes
29
- Array(@attributes) + Array(@relationships).map(&:name)
30
- end
31
-
32
- def mapping
33
- Array(@relationships).inject(t(:symbolize_keys) >> t(:accept_keys, all_attributes)) do |mapping, relationship|
34
- mapping >> t(:map_value, relationship.name, t(:mapping, relationship.mapper))
35
- end
36
- end
37
-
38
- def factory
39
- t(:factory, @entity)
40
- end
41
-
42
- def t(*args)
43
- Functions[*args]
44
- end
45
- end
46
- end
47
-
48
- class HashMapper < Mapper
49
- def self.mapping
50
- raise "Only one key, pair allowed" if @attributes.count > 1
51
- @map = t(:structure, @attributes.first.keys.first, @attributes.first.values.first)
52
- end
53
-
54
- def self.factory
55
- t(:map_array, super)
56
- end
57
- end
58
-
59
- class ArrayMapper < Mapper
60
- def self.mapping
61
- t(:map_array, t(:symbolize_keys) >> super)
62
- end
63
-
64
- def self.factory
65
- t(:map_array, super)
66
- end
67
- end
68
-
69
- class Relationship
70
- attr_reader :name, :mapper
71
-
72
- def initialize(name, mapper)
73
- @name = name
74
- @mapper = mapper
75
- end
76
- end
77
- end
@@ -1,20 +0,0 @@
1
- require 'api_mapper'
2
-
3
- require "github_mapper/entities/emoji"
4
- require "github_mapper/entities/user"
5
- require "github_mapper/entities/repository"
6
- require "github_mapper/entities/profile"
7
- require "github_mapper/entities/issue"
8
-
9
- require "github_mapper/mappers/emoji_mapper"
10
- require "github_mapper/mappers/user_mapper"
11
- require "github_mapper/mappers/profile_mapper"
12
- require "github_mapper/mappers/repositories_mapper"
13
- require "github_mapper/mappers/repository_mapper"
14
- require "github_mapper/mappers/issue_mapper"
15
-
16
- require "github_mapper/router"
17
-
18
- module GithibMapper
19
- # Your code goes here...
20
- end
@@ -1,5 +0,0 @@
1
- module GithubMapper
2
- class Emoji
3
- include Anima.new(:symbol, :url)
4
- end
5
- end
@@ -1,5 +0,0 @@
1
- module GithubMapper
2
- class Issue
3
- include Anima.new(:id, :number, :title, :user)
4
- end
5
- end
@@ -1,8 +0,0 @@
1
- module GithubMapper
2
- class Profile
3
- include Virtus.model
4
- attribute :id, Integer
5
- attribute :login
6
- attribute :hireable, Boolean
7
- end
8
- end
@@ -1,9 +0,0 @@
1
- module GithubMapper
2
- class Repository
3
- include Virtus.model
4
- attribute :id, Integer
5
- attribute :name
6
- attribute :full_name
7
- attribute :owner, GithubMapper::User
8
- end
9
- end
@@ -1,5 +0,0 @@
1
- module GithubMapper
2
- class User
3
- include Anima.new(:id, :login)
4
- end
5
- end
@@ -1,6 +0,0 @@
1
- module GithubMapper
2
- class EmojiMapper < ApiMapper::HashMapper
3
- attributes symbol: :url
4
- entity Emoji
5
- end
6
- end
@@ -1,8 +0,0 @@
1
- module GithubMapper
2
- class IssueMapper < ApiMapper::ArrayMapper
3
- attributes :id, :number, :title
4
- relationship :user, UserMapper
5
- entity Issue
6
- end
7
-
8
- end
@@ -1,7 +0,0 @@
1
- module GithubMapper
2
- class ProfileMapper < ApiMapper::Mapper
3
- attributes :id, :login, :hireable
4
- entity Profile
5
- end
6
-
7
- end
@@ -1,7 +0,0 @@
1
- module GithubMapper
2
- class RepositoriesMapper < ApiMapper::ArrayMapper
3
- attributes :id, :name, :full_name
4
- relationship :owner, UserMapper
5
- entity Repository
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module GithubMapper
2
- class RepositoryMapper < ApiMapper::Mapper
3
- attributes :id, :name, :full_name
4
- relationship :owner, UserMapper
5
- entity Repository
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module GithubMapper
2
- class UserMapper < ApiMapper::Mapper
3
- attributes :id, :login
4
- entity User
5
- end
6
-
7
- end
@@ -1,10 +0,0 @@
1
- module GithubMapper
2
- class Router < ApiMapper::Router
3
- get "emojis", EmojiMapper
4
- get "repositories", RepositoriesMapper
5
- post "user/repos", RepositoryMapper
6
- get "repos/{owner}/{repo}/issues", IssueMapper
7
- get "user", ProfileMapper
8
- patch "user", ProfileMapper
9
- end
10
- end