Module: FormatParser::AttributesJSON
- Included in:
- Archive, Audio, Document, Image, MP3Parser::TagWrapper, Text, Video, ZIPParser::FileReader::ZipEntry
- Defined in:
- lib/attributes_json.rb
Overview
Implements as_json as returning a Hash containing the return values of all the reader methods of an object that have associated pair writer methods.
class Foo
include AttributesJSON
attr_accessor :number_of_bars
end
the_foo = Foo.new
the_foo. = 42
the_foo.as_json #=> {:number_of_bars => 42}
Constant Summary collapse
- MAXIMUM_JSON_NESTING_WHEN_SANITIZING =
256
Class Method Summary collapse
-
._sanitize_json_value(value, nesting = 0) ⇒ Object
Used for sanitizing values that are sourced to ‘JSON::Generator::State#generate` The reason we need to do this is as follows: `JSON.generate / JSON.dump / JSON.pretty_generate` use a totally different code path than `“foo”.to_json(generator_state)`.
Instance Method Summary collapse
-
#as_json(root: false, stringify_keys: false) ⇒ Object
Implements a sane default ‘as_json` for an object that accessors defined.
-
#to_json(*maybe_generator_state) ⇒ Object
Implements to_json with sane defaults, with or without arguments.
Class Method Details
._sanitize_json_value(value, nesting = 0) ⇒ Object
Used for sanitizing values that are sourced to ‘JSON::Generator::State#generate` The reason we need to do this is as follows: `JSON.generate / JSON.dump / JSON.pretty_generate` use a totally different code path than `“foo”.to_json(generator_state)`. We cannot predict which one of these two ways our users will be using, and at the same time we need to prevent invalid Strings (ones which cannot be encoded into UTF-8) as well as Float::INFINITY values from being passed to the JSON encoder. Since we cannot override the JSON generator with these additions, instead we will deep-convert the entire object being output to make sure it is up to snuff.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/attributes_json.rb', line 53 def _sanitize_json_value(value, nesting = 0) raise ArgumentError, 'Nested JSON-ish structure too deep' if nesting > MAXIMUM_JSON_NESTING_WHEN_SANITIZING case value when Float # Float::NAN cannot be case-matched as it is does not equal itself. Float::INIFINITY can, # but it is easier to fold these two into a single case if value.nan? || value.infinite? nil else value end when String FormatParser.string_to_lossy_utf8(value) when Hash Hash[value.map { |k, v| [_sanitize_json_value(k, nesting + 1), _sanitize_json_value(v, nesting + 1)] }] when Array value.map { |v| _sanitize_json_value(v, nesting + 1) } when Struct _sanitize_json_value(value.to_h, nesting + 1) else value end end |
Instance Method Details
#as_json(root: false, stringify_keys: false) ⇒ Object
Implements a sane default ‘as_json` for an object that accessors defined
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/attributes_json.rb', line 23 def as_json(root: false, stringify_keys: false, **) h = {} h['nature'] = nature if respond_to?(:nature) # Needed for file info structs methods.grep(/\w\=$/).each_with_object(h) do |attr_writer_method_name, h| reader_method_name = attr_writer_method_name.to_s.gsub(/\=$/, '') attribute_value = public_send(reader_method_name) # When calling as_json on our members there is no need to pass # the root: option given to us by the caller unwrapped_attribute_value = attribute_value.respond_to?(:as_json) ? attribute_value.as_json : attribute_value sanitized_value = _sanitize_json_value(unwrapped_attribute_value) h[reader_method_name] = sanitized_value end h = FormatParser::HashUtils.deep_transform_keys(h, &:to_s) if stringify_keys if root {'format_parser_file_info' => h} else h end end |
#to_json(*maybe_generator_state) ⇒ Object
Implements to_json with sane defaults, with or without arguments
79 80 81 |
# File 'lib/attributes_json.rb', line 79 def to_json(*maybe_generator_state) as_json(root: false).to_json(*maybe_generator_state) end |