module SnakyHash::Serializer

Provides JSON serialization and deserialization capabilities with extensible value transformation

@example Basic usage

class MyHash < Hashie::Mash
  extend SnakyHash::Serializer
end
hash = MyHash.load('{"key": "value"}')
hash.dump #=> '{"key":"value"}'

Public Class Methods

extended(base) click to toggle source

Extends the base class with serialization capabilities

@param base [Class] the class being extended @return [void]

   # File lib/snaky_hash/serializer.rb
21 def extended(base)
22   extended_module = Modulizer.to_extended_mod
23   base.extend(extended_module)
24   base.include(ConvenienceInstanceMethods)
25   # :nocov:
26   # This will be run in CI on Ruby 2.3, but we only collect coverage from current Ruby
27   unless base.instance_methods.include?(:transform_values)
28     base.include(BackportedInstanceMethods)
29   end
30   # :nocov:
31 end

Public Instance Methods

dump(obj) click to toggle source

Serializes a hash object to JSON

@param obj [Hash] the hash to serialize @return [String] JSON string representation of the hash

   # File lib/snaky_hash/serializer.rb
38 def dump(obj)
39   hash = dump_hash(obj)
40   hash.to_json
41 end
load(raw_hash) click to toggle source

Deserializes a JSON string into a hash object

@param raw_hash [String, nil] JSON string to deserialize @return [Hash] deserialized hash object

   # File lib/snaky_hash/serializer.rb
47 def load(raw_hash)
48   hash = JSON.parse(presence(raw_hash) || "{}")
49   load_hash(new(hash))
50 end

Private Instance Methods

blank?(value) click to toggle source

Checks if a value is blank (nil or empty string)

@param value [Object] value to check @return [Boolean] true if value is blank

    # File lib/snaky_hash/serializer.rb
131 def blank?(value)
132   return true if value.nil?
133   return true if value.is_a?(String) && value.empty?
134 
135   false
136 end
dump_hash(hash) click to toggle source

Processes a hash for dumping, transforming its keys and/or values

@param hash [Hash] hash to process @return [Hash] processed hash with transformed values

    # File lib/snaky_hash/serializer.rb
150 def dump_hash(hash)
151   dump_hash_extensions.run(self[hash]).transform_values do |value|
152     dump_value(value)
153   end
154 end
dump_value(value) click to toggle source

Processes a single value for dumping

@param value [Object] value to process @return [Object, nil] processed value

    # File lib/snaky_hash/serializer.rb
160 def dump_value(value)
161   if blank?(value)
162     return value
163   end
164 
165   if value.is_a?(::Hash)
166     return dump_hash(value)
167   end
168 
169   if value.is_a?(::Array)
170     return value.map { |v| dump_value(v) }.compact
171   end
172 
173   dump_extensions.run(value)
174 end
load_hash(hash) click to toggle source

Processes a hash for loading, transforming its keys and/or values

@param hash [Hash] hash to process @return [Hash] processed hash with transformed values

    # File lib/snaky_hash/serializer.rb
180 def load_hash(hash)
181   ran = load_hash_extensions.run(self[hash])
182   return load_value(ran) unless ran.is_a?(::Hash)
183 
184   res = self[ran].transform_values do |value|
185     load_value(value)
186   end
187 
188   # TODO: Drop this hack when dropping support for Ruby 2.6
189   if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7")
190     res
191   else
192     # :nocov:
193     # In Ruby <= 2.6 Hash#transform_values returned a new vanilla Hash,
194     #   rather than a hash of the class being transformed.
195     self[res]
196     # :nocov:
197   end
198 end
load_value(value) click to toggle source

Processes a single value for loading

@param value [Object] value to process @return [Object, nil] processed value

    # File lib/snaky_hash/serializer.rb
204 def load_value(value)
205   if blank?(value)
206     return value
207   end
208 
209   if value.is_a?(::Hash)
210     return load_hash(value)
211   end
212 
213   if value.is_a?(::Array)
214     return value.map { |v| load_value(v) }.compact
215   end
216 
217   load_extensions.run(value)
218 end
presence(value) click to toggle source

Returns nil if value is blank, otherwise returns the value

@param value [Object] value to check @return [Object, nil] the value or nil if blank

    # File lib/snaky_hash/serializer.rb
142 def presence(value)
143   blank?(value) ? nil : value
144 end