Module: JSON
- Defined in:
- lib/neatjson.rb
Class Method Summary collapse
-
.neat_generate(object, opts = {}) ⇒ Object
The values returned for all keys must be all comparable, or an error will occur.
Class Method Details
.neat_generate(object, opts = {}) ⇒ Object
The values returned for all keys must be all comparable, or an error will occur.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/neatjson.rb', line 35 def self.neat_generate(object,opts={}) opts[:wrap] = 80 unless opts.key?(:wrap) opts[:wrap] = -1 if opts[:wrap]==true opts[:indent] ||= " " opts[:array_padding] ||= opts[:padding] || 0 opts[:object_padding] ||= opts[:padding] || 0 opts[:after_comma] ||= opts[:around_comma] || 0 opts[:before_comma] ||= opts[:around_comma] || 0 opts[:before_colon] ||= opts[:around_colon] || 0 opts[:after_colon] ||= opts[:around_colon] || 0 opts[:before_colon_1] ||= opts[:around_colon_1] || opts[:before_colon] || 0 opts[:after_colon_1] ||= opts[:around_colon_1] || opts[:after_colon] || 0 opts[:before_colon_n] ||= opts[:around_colon_n] || opts[:before_colon] || 0 opts[:after_colon_n] ||= opts[:around_colon_n] || opts[:after_colon] || 0 raise ":indent option must only be whitespace" if opts[:indent]=~/\S/ apad = " " * opts[:array_padding] opad = " " * opts[:object_padding] comma = "#{' '*opts[:before_comma]},#{' '*opts[:after_comma]}" colon1= "#{' '*opts[:before_colon_1]}:#{' '*opts[:after_colon_1]}" colonn= "#{' '*opts[:before_colon_n]}:#{' '*opts[:after_colon_n]}" memoizer = {} build = ->(o,indent) do memoizer[[o,indent]] ||= case o when String,Integer then "#{indent}#{o.inspect}" when Symbol then "#{indent}#{o.to_s.inspect}" when TrueClass,FalseClass then "#{indent}#{o}" when NilClass then "#{indent}null" when Float if (o==o.to_i) && (o.to_s !~ /e/) build[o.to_i,indent] elsif opts[:decimals] "#{indent}%.#{opts[:decimals]}f" % o else "#{indent}#{o}" end when Array if o.empty? "#{indent}[]" else pieces = o.map{ |v| build[v,''] } one_line = "#{indent}[#{apad}#{pieces.join comma}#{apad}]" if !opts[:wrap] || (one_line.length <= opts[:wrap]) one_line elsif opts[:short] indent2 = "#{indent} #{apad}" pieces = o.map{ |v| build[ v,indent2 ] } pieces[0].sub! indent2, "#{indent}[#{apad}" pieces.last << apad << "]" pieces.join ",\n" else indent2 = "#{indent}#{opts[:indent]}" "#{indent}[\n#{o.map{ |v| build[ v, indent2 ] }.join ",\n"}\n#{opts[:indent_last] ? indent2 : indent}]" end end when Hash if o.empty? "#{indent}{}" else case sort=(opts[:sorted] || opts[:sort]) when true then o = o.sort_by(&:first) when Proc o = case sort.arity when 1 then o.sort_by{ |k,v| sort[k] } when 2 then o.sort_by{ |k,v| sort[k,v] } when 3 then o.sort_by{ |k,v| sort[k,v,o] } end end keyvals = o.map{ |k,v| [ k.to_s.inspect, build[v,''] ] } keyvals = keyvals.map{ |kv| kv.join(colon1) }.join(comma) one_line = "#{indent}{#{opad}#{keyvals}#{opad}}" if !opts[:wrap] || (one_line.length <= opts[:wrap]) one_line else if opts[:short] keyvals = o.map{ |k,v| ["#{indent} #{opad}#{k.to_s.inspect}",v] } keyvals[0][0].sub! "#{indent} ", "#{indent}{" if opts[:aligned] longest = keyvals.map(&:first).map(&:length).max keyvals.each{ |k,v| k.replace( "%-#{longest}s" % k ) } end keyvals.map! do |k,v| indent2 = " "*"#{k}#{colonn}".length one_line = "#{k}#{colonn}#{build[v,'']}" if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash)) "#{k}#{colonn}#{build[v,indent2].lstrip}" else one_line end end keyvals.join(",\n") << opad << "}" else keyvals = o.map{ |k,v| ["#{indent}#{opts[:indent]}#{k.to_s.inspect}",v] } keyvals = keyvals.sort_by(&:first) if opts[:sorted] if opts[:aligned] longest = keyvals.map(&:first).map(&:length).max keyvals.each{ |k,v| k.replace( "%-#{longest}s" % k ) } end indent2 = "#{indent}#{opts[:indent]}" keyvals.map! do |k,v| one_line = "#{k}#{colonn}#{build[v,'']}" if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash)) "#{k}#{colonn}#{build[v,indent2].lstrip}" else one_line end end "#{indent}{\n#{keyvals.join(",\n")}\n#{opts[:indent_last] ? indent2 : indent}}" end end end else "#{indent}#{o.to_json(opts)}" end end build[object,''] end |