api_mapper 0.2.0 → 0.3.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
  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