hashstructor 1.0.6 → 1.1.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: 53417f9ad796f3bdbadd248016ebb1aed623160c
4
- data.tar.gz: 0a653553b55d4d333bc0be0d4d53d337beb7b7a5
3
+ metadata.gz: 09a0c03bda60b67da2ec5b83fc21e42b6347bfd9
4
+ data.tar.gz: 965e9e766544974d6afd2e70a94dc1339cd513f1
5
5
  SHA512:
6
- metadata.gz: 2f2ffb6a2a38ea3577dc2352d017af7b57f0ba5a4ada604703c4b500859b0ccb5c18328801e3a11555c9c4fd93d8792b2dcb18178723e3daf61c0c018ea21ec6
7
- data.tar.gz: 88e18912f12e341dc4427b015c6e594b9990e78f227d8cdc167ddf8f3d4f9d84b18089549d00546bc0d76bf1358b4de27670fc846c78478cf44e2beefa706af1
6
+ metadata.gz: 67d10c1f1d44188d219b2675ede43e3a3b4a7510b2824df4cdf8f808456326f4a7efc5d170ffb44b9886735afc358b7d2346fee8fadf93e838f5680929b07e34
7
+ data.tar.gz: a5635377333bcd518bf166d0f8e3a2080cbd24c420b241c6a09716e87ee6e1a5ff2e6367674e8ca6eb1ce748e08599d2faeaf85c551d438c9861ad00eb987851
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  There comes a time in every wee programmer's life (and all programmers are, for the purposes of this readme, wee or previously wee) when one must take a big blob of JSON or YAML and make it into an object. Or worse, a hierarchy of objects. This leads to lots of very manual parsing and gnashing of teeth. Some libraries, like the mildly spiffy [constructor](https://github.com/atomicobject/constructor), allow you to defray some of this pain by letting you pass in hashes to build objects, but this only goes so far: no type coercion, no nested types.
4
4
 
5
- Finally I got tired of this mess when building a game prototype and writing enough stupid read-in code of data files that I decided to Fix This Situation. (You can argue that I got sidetracked; I won't disagree.) After about three hours of late-night work, I'm somewhat proud to unveil **Hashstructor**: your one-stop shop for mangling the heck out of Ruby hashes and building neat-o object trees out of them. (The reverse, breaking these data structures down into hashes, is a TODO.)
5
+ Finally I got tired of this mess when building a game prototype and writing enough stupid read-in code of data files that I decided to Fix This Situation. (You can argue that I got sidetracked; I won't disagree.) After about three hours of late-night work, I'm somewhat proud to unveil **Hashstructor**: your one-stop shop for mangling the heck out of Ruby hashes and building neat-o object trees out of them. You can also turn them back into hashes with `#to_hash`--I've found this really useful for transient domain objects in message queues. The creator can create objects with validation and structure and then `#to_hash` them when they go into the queue, and the same can be done when you get them back out.
6
6
 
7
7
  Hashstructor is _fully documented_ (100% coverage in `yard`) and comes with a fairly exhaustive set of tests to prove that it actually does what it's supposed to do.
8
8
 
@@ -3,6 +3,57 @@ require 'set'
3
3
  module Hashstructor
4
4
  # Instance methods for {Hashstructor} objects.
5
5
  module InstanceMethods
6
+
7
+
8
+ # Converts the class back to a hash.
9
+ #
10
+ # @returns [Hash] the hash representation of this class
11
+ def to_h
12
+ to_hash
13
+ end
14
+
15
+ # Converts the class back to a hash.
16
+ #
17
+ # @returns [Hash] the hash representation of this class
18
+ def to_hash
19
+ hash = {}
20
+
21
+ self.class.hashstructor_members.each do |member|
22
+ member_value = instance_variable_get("@#{member.name}")
23
+
24
+ out_value =
25
+ case member.member_type
26
+ when :normal
27
+ member_value.nil? ? nil : member.to_hash_value(member_value)
28
+ when :array
29
+ # There's some weird Ruby thing I don't get here, but if I use
30
+ # a #select instead of an each + container, I end up returning
31
+ # the actual objects rather than their to_hashes.
32
+ container = []
33
+ member_value.each do |v|
34
+ container << member.to_hash_value(v)
35
+ end
36
+ container
37
+ when :set
38
+ container = Set.new
39
+ member_value.each do |v|
40
+ container << member.to_hash_value(v)
41
+ end
42
+ container
43
+ when :hash
44
+ container = {}
45
+ member_value.each do |k, v|
46
+ container[k] = member.to_hash_value(v)
47
+ end
48
+ container
49
+ end
50
+
51
+ hash[member.name.to_sym] = out_value
52
+ end
53
+
54
+ hash
55
+ end
56
+
6
57
  private
7
58
  # Initializes the object. This exists for objects that `prepend`
8
59
  # {Hashstructor}; objects that `include` it must explicitly invoke
@@ -51,20 +51,32 @@ module Hashstructor
51
51
  # not frozen; if you want to extend it for your own use cases, I'm not
52
52
  # going to get in your way.
53
53
  VALID_VALUE_TYPES = {
54
- String => Proc.new do |v|
55
- v.to_s
56
- end,
57
- Symbol => Proc.new do |v|
58
- v.to_sym
59
- end,
60
- Integer => Proc.new do |v|
61
- Integer(v.to_s)
62
- end,
63
- Float => Proc.new do |v|
64
- Float(v.to_s)
65
- end,
66
- TrueClass => BOOL_PROC,
67
- FalseClass => BOOL_PROC,
54
+ String => {
55
+ :in => Proc.new do |v|
56
+ v.to_s
57
+ end
58
+ },
59
+ Symbol => {
60
+ :in => Proc.new do |v|
61
+ v.to_sym
62
+ end
63
+ },
64
+ Integer => {
65
+ :in => Proc.new do |v|
66
+ Integer(v.to_s)
67
+ end
68
+ },
69
+ Float => {
70
+ :in => Proc.new do |v|
71
+ Float(v.to_s)
72
+ end
73
+ },
74
+ TrueClass => {
75
+ :in => BOOL_PROC
76
+ },
77
+ FalseClass => {
78
+ :in => BOOL_PROC
79
+ },
68
80
  }
69
81
  # Determines the class that Hashstructor should attempt to coerce a
70
82
  # given value into. For example, `Fixnum` will attempt to coerce a
@@ -159,7 +171,7 @@ module Hashstructor
159
171
 
160
172
  value_type.new(value)
161
173
  else
162
- VALID_VALUE_TYPES[value_type].call(value)
174
+ VALID_VALUE_TYPES[value_type][:in].call(value)
163
175
  end
164
176
 
165
177
  if options[:validation]
@@ -173,5 +185,29 @@ module Hashstructor
173
185
 
174
186
  retval
175
187
  end
188
+
189
+ # The inverse of {#parse_single}, which turns a hashstructed member into a hash value. This should
190
+ # always be a strict inverse; anything this returns should be able to be fed into {#parse_single}
191
+ # to return the value passed into this function in the first place.
192
+ def to_hash_value(member_value)
193
+ if member_value.class.ancestors.include?(Hashstructor)
194
+ member_value.to_hash
195
+ else
196
+ out_proc = VALID_VALUE_TYPES[value_type][:out]
197
+
198
+ if (out_proc && !value_type.nil?)
199
+ out_proc.call(member_value)
200
+ else
201
+ if member_value.respond_to?(:to_h)
202
+ member_value.to_h
203
+ elsif member_value.respond_to?(:to_hash)
204
+ member_value.to_hash
205
+ else
206
+ member_value
207
+ end
208
+ end
209
+ end
210
+ end
211
+
176
212
  end
177
213
  end
@@ -1,4 +1,4 @@
1
1
  module Hashstructor
2
2
  # The gem version. As one does.
3
- VERSION = "1.0.6"
3
+ VERSION = "1.1.0"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashstructor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ed Ropple
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-23 00:00:00.000000000 Z
11
+ date: 2015-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
124
124
  version: '0'
125
125
  requirements: []
126
126
  rubyforge_project:
127
- rubygems_version: 2.4.6
127
+ rubygems_version: 2.4.5
128
128
  signing_key:
129
129
  specification_version: 4
130
130
  summary: A Ruby DSL and parser for converting hashes into trees of data objects.