mimi-struct 0.1.0 → 1.0.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 +4 -4
- data/.gitignore +2 -3
- data/bin/console +2 -6
- data/examples/nested.rb +29 -0
- data/examples/poro.rb +23 -0
- data/examples/simple.rb +13 -0
- data/lib/mimi/struct.rb +36 -31
- data/lib/mimi/struct/version.rb +1 -3
- data/mimi-struct.gemspec +3 -2
- metadata +21 -5
- data/Gemfile.lock +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8064ab3ebc35af445e5be33a322db6d14a31693e
|
4
|
+
data.tar.gz: f8d1a850531925e12fe0c473647dc519538072f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d62b706cf2bffafb74bd09ead748382b95e1a4d297c6976832968065f5ecc7c9a6ca65b9daa7baed14f741c46719891ceaa23fcd7fdc921b8a73b0344e90fea
|
7
|
+
data.tar.gz: ad312292e8c75438467baa6754658f26e101040dd9ee1121dc6a4ddf349975c09d72f5ebe72e91566ddc384a33a8e3bd6fe835d982373de8dce817ddc9a8c506
|
data/.gitignore
CHANGED
data/bin/console
CHANGED
@@ -6,9 +6,5 @@ require "mimi/struct"
|
|
6
6
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
7
|
# with your gem easier. You can also use a different console, if you like.
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
9
|
+
require "pry"
|
10
|
+
Pry.start
|
data/examples/nested.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "mimi/struct"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
class User < Mimi::Struct
|
5
|
+
attribute :id
|
6
|
+
attribute :name, from: :username
|
7
|
+
end
|
8
|
+
|
9
|
+
class Comment < Mimi::Struct
|
10
|
+
attribute :author, from: :user, using: User
|
11
|
+
attribute :text
|
12
|
+
end
|
13
|
+
|
14
|
+
class Post < Mimi::Struct
|
15
|
+
attribute :id
|
16
|
+
attribute :author, using: User
|
17
|
+
attribute :text
|
18
|
+
attribute :comments, using: Comment
|
19
|
+
end
|
20
|
+
|
21
|
+
user1 = { id: 1, username: "Alice", email: "alice@gmail.com" }
|
22
|
+
user2 = { id: 2, username: "Bob", email: "bob@gmail.com" }
|
23
|
+
comm1 = { user: user1, text: "Mmm?" }
|
24
|
+
comm2 = { user: user2, text: "Hi!" }
|
25
|
+
post_params = { id: 1, author: user1, text: "Hello, world!", comments: [comm1, comm2] }
|
26
|
+
|
27
|
+
# Maps Post including all nested data
|
28
|
+
post = Post.new(post_params)
|
29
|
+
puts JSON.pretty_generate post.to_h
|
data/examples/poro.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "mimi/struct"
|
2
|
+
|
3
|
+
#
|
4
|
+
# Mapping a PORO
|
5
|
+
#
|
6
|
+
|
7
|
+
class User < Mimi::Struct
|
8
|
+
attribute :id
|
9
|
+
attribute :name, from: :username
|
10
|
+
end
|
11
|
+
|
12
|
+
class UserData
|
13
|
+
attr_reader :id, :username
|
14
|
+
|
15
|
+
def initialize(username)
|
16
|
+
@id = rand(1000)
|
17
|
+
@username = username
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
user_data = UserData.new("John")
|
22
|
+
|
23
|
+
puts User.new(user_data).to_h
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "mimi/struct"
|
2
|
+
|
3
|
+
# Simple data mapping
|
4
|
+
#
|
5
|
+
class User < Mimi::Struct
|
6
|
+
attribute :id
|
7
|
+
attribute :name, from: :username
|
8
|
+
end
|
9
|
+
|
10
|
+
# Maps defined attributes, filters out all the extra attributes:
|
11
|
+
user = User.new(id: 1, username: "John", email: "john@gmail.com")
|
12
|
+
|
13
|
+
puts user.to_h
|
data/lib/mimi/struct.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "mimi/core"
|
4
|
+
|
3
5
|
module Mimi
|
4
6
|
#
|
5
|
-
# A Struct that can be initialized from a Hash or
|
7
|
+
# A Struct that can be initialized from a Hash or a PORO.
|
6
8
|
#
|
7
|
-
# A Struct declares its attributes and rules, which define how its
|
9
|
+
# A Struct declares its attributes and rules, which define how its attributes
|
8
10
|
# are mapped from input data.
|
9
11
|
#
|
10
|
-
class Struct < ::Struct
|
11
|
-
|
12
|
+
class Struct < Mimi::Core::Struct
|
13
|
+
#
|
12
14
|
# Default attribute mapper
|
13
15
|
#
|
14
16
|
# Maps value of the source attribute to the target attribute.
|
@@ -16,9 +18,9 @@ module Mimi
|
|
16
18
|
#
|
17
19
|
DEFAULT_ATTRIBUTE_MAPPER = -> (o, params) do
|
18
20
|
if params.key?(:default)
|
19
|
-
o.
|
21
|
+
o.respond_to?(params[:from]) || call_as_proc(params[:default], o, params)
|
20
22
|
else
|
21
|
-
o
|
23
|
+
o.send(params[:from])
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -27,7 +29,27 @@ module Mimi
|
|
27
29
|
# Skips the attribute if the source attribute is not set.
|
28
30
|
#
|
29
31
|
DEFAULT_IF_FOR_OPTIONAL = -> (o, params) do
|
30
|
-
o.
|
32
|
+
o.respond_to?(params[:from])
|
33
|
+
end
|
34
|
+
|
35
|
+
# Creates a mapped Struct object from another object
|
36
|
+
#
|
37
|
+
# @param source [Hash,Object]
|
38
|
+
#
|
39
|
+
def initialize(source)
|
40
|
+
source = Mimi::Core::Struct.new(source) if source.is_a?(Hash)
|
41
|
+
attributes = self.class.transform_attributes(source)
|
42
|
+
super(attributes)
|
43
|
+
rescue StandardError => e
|
44
|
+
raise e.class, "Failed to construct #{self.class}: #{e}", e.backtrace
|
45
|
+
end
|
46
|
+
|
47
|
+
# Fetches an attribute with given name
|
48
|
+
#
|
49
|
+
# @param name [Symbol]
|
50
|
+
#
|
51
|
+
def [](name)
|
52
|
+
@attributes[name.to_sym]
|
31
53
|
end
|
32
54
|
|
33
55
|
# Presents this Struct as a Hash, deeply converting nested Structs
|
@@ -35,7 +57,7 @@ module Mimi
|
|
35
57
|
# @return [Hash]
|
36
58
|
#
|
37
59
|
def to_h
|
38
|
-
|
60
|
+
attributes.map do |k, v|
|
39
61
|
[k, self.class.value_to_h(v)]
|
40
62
|
end.to_h
|
41
63
|
end
|
@@ -45,7 +67,7 @@ module Mimi
|
|
45
67
|
# @return [Hash]
|
46
68
|
#
|
47
69
|
def attributes
|
48
|
-
|
70
|
+
@attributes
|
49
71
|
end
|
50
72
|
|
51
73
|
# An attribute definition
|
@@ -109,7 +131,7 @@ module Mimi
|
|
109
131
|
if obj_or_collection.is_a?(Array)
|
110
132
|
obj_or_collection.map { |o| self << o }
|
111
133
|
else
|
112
|
-
|
134
|
+
new(obj_or_collection)
|
113
135
|
end
|
114
136
|
end
|
115
137
|
|
@@ -141,36 +163,19 @@ module Mimi
|
|
141
163
|
@group_params ||= [{}]
|
142
164
|
end
|
143
165
|
|
144
|
-
# Creates a Struct instance from given parameters
|
145
|
-
#
|
146
|
-
# @param source [Struct,Hash]
|
147
|
-
#
|
148
|
-
private_class_method def self.transform(source)
|
149
|
-
if source.is_a?(Struct)
|
150
|
-
# do nothing
|
151
|
-
elsif source.is_a?(Hash)
|
152
|
-
source = Struct.new(*source.to_h.keys).new(*source.to_h.values)
|
153
|
-
else
|
154
|
-
raise ArgumentError, "Struct or Hash is expected as source"
|
155
|
-
end
|
156
|
-
attributes = transform_attributes(source)
|
157
|
-
new(*attributes.keys).new(*attributes.values)
|
158
|
-
rescue StandardError => e
|
159
|
-
raise "Failed to construct #{self}: #{e}"
|
160
|
-
end
|
161
|
-
|
162
166
|
# Transform attributes according to rules
|
163
167
|
#
|
164
168
|
# @param source [Struct]
|
165
169
|
# @return [Hash] map of attribute name -> value
|
166
170
|
#
|
167
|
-
|
168
|
-
attribute_definitions.map do |k, params|
|
171
|
+
def self.transform_attributes(source)
|
172
|
+
result = attribute_definitions.map do |k, params|
|
169
173
|
if params[:if].is_a?(Proc)
|
170
174
|
next unless call_as_proc(params[:if], source, params)
|
171
175
|
end
|
172
176
|
[k, transform_single_attribute(source, k, params)]
|
173
177
|
end.compact.to_h
|
178
|
+
result
|
174
179
|
end
|
175
180
|
|
176
181
|
# Transforms a single attribute value according to rules passed as params
|
@@ -183,7 +188,7 @@ module Mimi
|
|
183
188
|
private_class_method def self.transform_single_attribute(source, key, params)
|
184
189
|
return call_as_proc(params[:using], source, params) if params[:using].is_a?(Proc)
|
185
190
|
if params[:using].is_a?(Class) && params[:using] < Mimi::Struct
|
186
|
-
return params[:using] << source
|
191
|
+
return params[:using] << source.send(params[:from])
|
187
192
|
end
|
188
193
|
raise "unexpected :using type: #{params[:using].class}"
|
189
194
|
rescue StandardError => e
|
data/lib/mimi/struct/version.rb
CHANGED
data/mimi-struct.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
lib = File.expand_path("lib", __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require "mimi/struct
|
3
|
+
require "mimi/struct"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "mimi-struct"
|
@@ -30,9 +30,10 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
|
-
spec.add_dependency "mimi-core", "~> 1.
|
33
|
+
spec.add_dependency "mimi-core", "~> 1.1"
|
34
34
|
|
35
35
|
spec.add_development_dependency "bundler", "~> 2.0"
|
36
|
+
spec.add_development_dependency "pry", "~> 0.12"
|
36
37
|
spec.add_development_dependency "rake", "~> 10.0"
|
37
38
|
spec.add_development_dependency "rspec", "~> 3.0"
|
38
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mimi-struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Kukushkin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mimi-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
26
|
+
version: '1.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.12'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.12'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,13 +92,15 @@ files:
|
|
78
92
|
- ".travis.yml"
|
79
93
|
- CODE_OF_CONDUCT.md
|
80
94
|
- Gemfile
|
81
|
-
- Gemfile.lock
|
82
95
|
- LICENSE.txt
|
83
96
|
- README.md
|
84
97
|
- Rakefile
|
85
98
|
- bin/console
|
86
99
|
- bin/setup
|
87
100
|
- examples/customer.rb
|
101
|
+
- examples/nested.rb
|
102
|
+
- examples/poro.rb
|
103
|
+
- examples/simple.rb
|
88
104
|
- lib/mimi/struct.rb
|
89
105
|
- lib/mimi/struct/version.rb
|
90
106
|
- mimi-struct.gemspec
|
data/Gemfile.lock
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
mimi-struct (0.1.0)
|
5
|
-
mimi-core (~> 1.0)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
diff-lcs (1.3)
|
11
|
-
hashie (3.6.0)
|
12
|
-
mimi-core (1.0.0)
|
13
|
-
hashie (~> 3.6)
|
14
|
-
rake (10.5.0)
|
15
|
-
rspec (3.8.0)
|
16
|
-
rspec-core (~> 3.8.0)
|
17
|
-
rspec-expectations (~> 3.8.0)
|
18
|
-
rspec-mocks (~> 3.8.0)
|
19
|
-
rspec-core (3.8.1)
|
20
|
-
rspec-support (~> 3.8.0)
|
21
|
-
rspec-expectations (3.8.4)
|
22
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
23
|
-
rspec-support (~> 3.8.0)
|
24
|
-
rspec-mocks (3.8.1)
|
25
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
26
|
-
rspec-support (~> 3.8.0)
|
27
|
-
rspec-support (3.8.2)
|
28
|
-
|
29
|
-
PLATFORMS
|
30
|
-
ruby
|
31
|
-
|
32
|
-
DEPENDENCIES
|
33
|
-
bundler (~> 2.0)
|
34
|
-
mimi-struct!
|
35
|
-
rake (~> 10.0)
|
36
|
-
rspec (~> 3.0)
|
37
|
-
|
38
|
-
BUNDLED WITH
|
39
|
-
2.0.2
|