structformatter 0.0.1

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.
@@ -0,0 +1 @@
1
+ �C��|.#��?��/O�gt0� 7�ߦ�K/)#7�3��0뒺�D
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in structformatter.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 chrislee35
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ # Structformatter
2
+
3
+ Structformatter extends ruby Structs, Arrays, and Hashes to be outputted as yaml, xml, and json.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'structformatter'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install structformatter
18
+
19
+ ## Usage
20
+
21
+ require 'structformatter'
22
+
23
+ class TestStruct < Struct.new(:apple,:bottle,:can,:donut); end
24
+ a = [1,'test',1.0,1e-9]
25
+ b = {'a'=>1, 'b'=>1.0, 'c'=>1e-9, 'd'=>'test'}
26
+ c = TestStruct.new(1,1.0,1e-9,'test')
27
+ a.to_xml
28
+ a.to_json
29
+ a.to_s
30
+ b.to_xml
31
+ b.to_json
32
+ b.to_s
33
+ c.to_xml
34
+ c.to_json
35
+ c.to_s(",")
36
+
37
+ ## Contributing
38
+
39
+ 1. Fork it
40
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
41
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
42
+ 4. Push to the branch (`git push origin my-new-feature`)
43
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/test_*.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,177 @@
1
+ require "structformatter/version"
2
+ # DESCRIPTION: extends ruby Structs, Arrays, and Hashes to be outputted as yaml, xml, and strings. This is meant to be used as a mixin
3
+ require 'json'
4
+ require 'date'
5
+
6
+ class String
7
+ def xml_escape
8
+ self.gsub(/&/,"&amp;").gsub(/"/, "&quot;").gsub(/'/, "&apros;").gsub(/</,"&lt;").gsub(/>/,"&gt;")
9
+ end
10
+ def xml_escape!
11
+ self.gsub!(/&/,"&amp;")
12
+ self.gsub!(/"/, "&quot;")
13
+ self.gsub!(/'/, "&apros;")
14
+ self.gsub!(/</,"&lt;")
15
+ self.gsub!(/>/,"&gt;")
16
+ end
17
+ end
18
+
19
+ class Array
20
+ def render_xml(element_name, element)
21
+ str = ""
22
+ if element.class == Date
23
+ str = "<#{element_name}>#{element.strftime("%Y-%m-%d")}</#{element_name}>"
24
+ elsif element.class == Time or element.class == DateTime
25
+ str = "<#{element_name}>#{element.strftime("%Y-%m-%dT%H:%M:%SZ")}</#{element_name}>"
26
+ elsif element.kind_of? Struct or element.kind_of? Hash or element.kind_of? Array
27
+ str = element.to_xml
28
+ else
29
+ str = "<#{element_name}>#{element.to_s.xml_escape}</#{element_name}>"
30
+ end
31
+ end
32
+ def to_xml
33
+ str = "<array>"
34
+ self.each do |item|
35
+ str += render_xml("element",item)
36
+ end
37
+ str += "</array>"
38
+ end
39
+ def to(format)
40
+ case format
41
+ when 'xml'
42
+ self.to_xml
43
+ when 'json'
44
+ self.to_json
45
+ when 'string'
46
+ self.to_s
47
+ else
48
+ raise "invalid format: #{format}, use one of xml, json, or string"
49
+ end
50
+ end
51
+ end
52
+
53
+ class Hash
54
+ def render_xml(element_name, element)
55
+ str = ""
56
+ if element.class == Date
57
+ str = "<#{element_name}>#{element.strftime("%Y-%m-%d")}</#{element_name}>"
58
+ elsif element.class == Time or element.class == DateTime
59
+ str = "<#{element_name}>#{element.strftime("%Y-%m-%dT%H:%M:%SZ")}</#{element_name}>"
60
+ elsif element.kind_of? Struct or element.kind_of? Hash or element.kind_of? Array
61
+ str = element.to_xml
62
+ else
63
+ str = "<#{element_name}>#{element.to_s.xml_escape}</#{element_name}>"
64
+ end
65
+ end
66
+ def to_xml
67
+ str = "<hash>"
68
+ self.each do |key,value|
69
+ str += "<element><key>#{key}</key>"
70
+ str += render_xml("value",value)
71
+ str += "</element>"
72
+ end
73
+ str += "</hash>"
74
+ end
75
+ def to(format)
76
+ case format
77
+ when 'xml'
78
+ self.to_xml
79
+ when 'json'
80
+ self.to_json
81
+ when 'string'
82
+ self.to_s
83
+ else
84
+ raise "invalid format: #{format}, use one of xml, json, or string"
85
+ end
86
+ end
87
+ end
88
+
89
+ class Struct
90
+ @@printclass = true
91
+ def Struct::printclass=(pc)
92
+ @@printclass = pc
93
+ end
94
+ def render_xml(element_name, element)
95
+ str = ""
96
+ if element.class == Date
97
+ str = "<#{element_name}>#{element.strftime("%Y-%m-%d")}</#{element_name}>"
98
+ elsif element.class == Time or element.class == DateTime
99
+ str = "<#{element_name}>#{element.strftime("%Y-%m-%dT%H:%M:%SZ")}</#{element_name}>"
100
+ elsif element.kind_of? Struct
101
+ str = element.to_xml
102
+ elsif element.kind_of? Hash or element.kind_of? Array
103
+ str = "<#{element_name}>"+element.to_xml+"</#{element_name}>"
104
+ else
105
+ str = "<#{element_name}>#{element.to_s.xml_escape}</#{element_name}>"
106
+ end
107
+ end
108
+ def to_xml
109
+ children = []
110
+ str = "<#{self.class}"
111
+ self.members.each do |member|
112
+ if self[member].class == Array or self[member].class == Hash or self[member].kind_of? Struct
113
+ children << member
114
+ elsif self[member].class == Date
115
+ str += " #{member}='#{self[member].strftime("%Y-%m-%d")}'"
116
+ elsif self[member].class == Time
117
+ str += " #{member}='#{self[member].strftime("%Y-%m-%dT%H:%M:%SZ")}'"
118
+ else
119
+ str += " #{member}='#{self[member].to_s.xml_escape}'"
120
+ end
121
+ end
122
+ if children.length == 0
123
+ str += ' />'
124
+ else
125
+ str += '>'
126
+ children.each do |member|
127
+ if self[member].class == Array
128
+ str += "<#{member}s>"
129
+ self[member].each do |item|
130
+ str += render_xml(member,item)
131
+ end
132
+ str += "</#{member}s>"
133
+ elsif self[member].class == Hash
134
+ str += "<#{member}s>"
135
+ self[member].each do |key,value|
136
+ str += "<HashElement><key>#{key}</key><value>"
137
+ str += render_xml(member,value)
138
+ str += "</value></HashElement>"
139
+ end
140
+ str += "</#{member}s>"
141
+ elsif self[member].kind_of? Struct
142
+ str += self[member].to_xml
143
+ end
144
+ end
145
+ str += "</#{self.class}>"
146
+ end
147
+ end
148
+
149
+ def to_json(*a)
150
+ hash = (@@printclass) ? { 'class' => self.class } : {}
151
+ self.members.sort.each do |member|
152
+ hash[member] = self[member]
153
+ end
154
+ hash.to_json(*a)
155
+ end
156
+
157
+ def to(format)
158
+ case format
159
+ when 'xml'
160
+ self.to_xml
161
+ when 'json'
162
+ self.to_json
163
+ when 'string'
164
+ self.to_s
165
+ else
166
+ raise "invalid format: #{format}, use one of xml, json, or string"
167
+ end
168
+ end
169
+
170
+ def to_s(sep = " ")
171
+ self.members.map{ |x| self[x].to_s }.join(sep)
172
+ end
173
+
174
+ def to_s_header(sep = " ")
175
+ self.members.map{ |x| x.to_s }.join(sep)
176
+ end
177
+ end
@@ -0,0 +1,3 @@
1
+ module Structformatter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'structformatter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "structformatter"
8
+ spec.version = Structformatter::VERSION
9
+ spec.authors = ["chrislee35"]
10
+ spec.email = ["rubygems@chrislee.dhs.org"]
11
+ spec.description = %q{Extends Structs, Hashes, and Arrays with .to_json, .to_xml, and .to_s. This handles nested data structures and some oddities that other methods do not.}
12
+ spec.summary = %q{Extends Structs, Hashes, and Arrays with .to_json, .to_xml, and .to_s}
13
+ spec.homepage = "https://github.com/chrislee35/structformatter"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "json", ">= 1.4.3"
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+
25
+ spec.signing_key = "#{File.dirname(__FILE__)}/../gem-private_key.pem"
26
+ spec.cert_chain = ["#{File.dirname(__FILE__)}/../gem-public_cert.pem"]
27
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require File.expand_path('../../lib/structformatter.rb', __FILE__)
@@ -0,0 +1,94 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'helper'
10
+
11
+ class TestStruct < Struct.new(:apple,:bottle,:can,:donut); end
12
+
13
+ class TestStructformatter < Test::Unit::TestCase
14
+ def test_simple_structures
15
+ a = [1,'test',1.0,1e-9]
16
+ assert_equal(
17
+ "<array><element>1</element><element>test</element><element>1.0</element><element>1.0e-09</element></array>",
18
+ a.to_xml
19
+ )
20
+ assert_equal(
21
+ '[1,"test",1.0,1.0e-09]',
22
+ a.to_json
23
+ )
24
+ # fails in 1.8
25
+ assert_equal(
26
+ '[1, "test", 1.0, 1.0e-09]',
27
+ a.to_s
28
+ )
29
+ # fails in 1.8
30
+ b = {'a'=>1, 'b'=>1.0, 'c'=>1e-9, 'd'=>'test'}
31
+ assert_equal(
32
+ "<hash><element><key>a</key><value>1</value></element><element><key>b</key><value>1.0</value></element><element><key>c</key><value>1.0e-09</value></element><element><key>d</key><value>test</value></element></hash>",
33
+ b.to_xml
34
+ )
35
+ assert_equal(
36
+ '{"a":1,"b":1.0,"c":1.0e-09,"d":"test"}',
37
+ b.to_json
38
+ )
39
+ assert_equal(
40
+ '{"a"=>1, "b"=>1.0, "c"=>1.0e-09, "d"=>"test"}',
41
+ b.to_s
42
+ )
43
+
44
+ c = TestStruct.new(1,1.0,1e-9,'test')
45
+ assert_equal(
46
+ "<TestStruct apple='1' bottle='1.0' can='1.0e-09' donut='test' />",
47
+ c.to_xml
48
+ )
49
+ assert_equal(
50
+ '{"class":"TestStruct","apple":1,"bottle":1.0,"can":1.0e-09,"donut":"test"}',
51
+ c.to_json
52
+ )
53
+ assert_equal(
54
+ '1 1.0 1.0e-09 test',
55
+ c.to_s
56
+ )
57
+ end
58
+
59
+ def test_complex_structure
60
+ a = TestStruct.new(
61
+ [1,'test',{'a'=>1,'b'=>2.0},Date.parse("2010-10-10")],
62
+ {'k'=>['j','<bad>']},
63
+ TestStruct.new(5,4,3,2),
64
+ true
65
+ )
66
+ # all of these will fail in 1.8
67
+ assert_equal(
68
+ "<TestStruct donut='true'><apples><apple>1</apple><apple>test</apple><apple><hash><element><key>a</key><value>1</value></element><element><key>b</key><value>2.0</value></element></hash></apple><apple>2010-10-10</apple></apples><bottles><HashElement><key>k</key><value><bottle><array><element>j</element><element>&lt;bad&gt;</element></array></bottle></value></HashElement></bottles><TestStruct apple='5' bottle='4' can='3' donut='2' /></TestStruct>",
69
+ a.to_xml
70
+ )
71
+ assert_equal(
72
+ '{"class":"TestStruct","apple":[1,"test",{"a":1,"b":2.0},"2010-10-10"],"bottle":{"k":["j","<bad>"]},"can":{"class":"TestStruct","apple":5,"bottle":4,"can":3,"donut":2},"donut":true}',
73
+ a.to_json
74
+ )
75
+ assert_equal(
76
+ '[1, "test", {"a"=>1, "b"=>2.0}, #<Date: 2010-10-10 ((2455480j,0s,0n),+0s,2299161j)>] {"k"=>["j", "<bad>"]} 5 4 3 2 true',
77
+ a.to_s
78
+ )
79
+ end
80
+
81
+ def test_csv_out
82
+ a = [
83
+ TestStruct.new(1,2,3,4),
84
+ TestStruct.new(5,6,7,8),
85
+ TestStruct.new(9,10,11,12),
86
+ TestStruct.new(13,14,15,16)
87
+ ]
88
+ assert_equal("apple,bottle,can,donut", a[0].to_s_header(","))
89
+ assert_equal("1,2,3,4", a[0].to_s(","))
90
+ assert_equal("5,6,7,8", a[1].to_s(","))
91
+ assert_equal("9,10,11,12", a[2].to_s(","))
92
+ assert_equal("13,14,15,16", a[3].to_s(","))
93
+ end
94
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: structformatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - chrislee35
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain:
12
+ - !binary |-
13
+ LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZakNDQWtxZ0F3SUJB
14
+ Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREJYTVJFd0R3WURWUVFEREFoeWRX
15
+ SjUKWjJWdGN6RVlNQllHQ2dtU0pvbVQ4aXhrQVJrV0NHTm9jbWx6YkdWbE1S
16
+ TXdFUVlLQ1pJbWlaUHlMR1FCR1JZRApaR2h6TVJNd0VRWUtDWkltaVpQeUxH
17
+ UUJHUllEYjNKbk1CNFhEVEV6TURVeU1qRXlOVGswTjFvWERURTBNRFV5Ck1q
18
+ RXlOVGswTjFvd1Z6RVJNQThHQTFVRUF3d0ljblZpZVdkbGJYTXhHREFXQmdv
19
+ SmtpYUprL0lzWkFFWkZnaGoKYUhKcGMyeGxaVEVUTUJFR0NnbVNKb21UOGl4
20
+ a0FSa1dBMlJvY3pFVE1CRUdDZ21TSm9tVDhpeGtBUmtXQTI5eQpaekNDQVNJ
21
+ d0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOY1ByeDhC
22
+ WmlXSVI5eFdXRzhJCnRxUjUzOHRTMXQrVUo0RlpGbCsxdnJ0VTlUaXVXWDNW
23
+ ajM3VHdVcGEyZkZremlLMG41S3VwVlRoeUVoY2VtNW0KT0dSanZnclJGYldR
24
+ SlNTc2NJS09wd3FVUkhWS1JwVjlnVnovSG56azhTK3hvdFVSMUJ1bzNVZ3Ir
25
+ STFqSGV3RApDZ3IreSt6Z1pidGp0SHNKdHN1dWprT2NQaEVqalVpbmo2OEw5
26
+ Rno5QmRlSlF0K0lhY2p3QXpVTGl4NmpXQ2h0ClVjK2crMHo4RXNyeWNhMkc2
27
+ STFHc3JnWDZXSHc4ZHlreVFEVDlkQ3RTMmZsQ093U0MxUjBLNVQveEhXNTRm
28
+ KzUKd2N3OG1tNTNLTE5lK3RtZ1ZDNlpIeU1FK3FKc0JuUDZ1eEYwYVRFbkdB
29
+ L2pEQlFEaFFOVEYwWlAvYWJ6eVRzTAp6alVDQXdFQUFhTTVNRGN3Q1FZRFZS
30
+ MFRCQUl3QURBTEJnTlZIUThFQkFNQ0JMQXdIUVlEVlIwT0JCWUVGTzh3Cith
31
+ ZVA3VDZrVkpibENnNmV1c09JSTlEZk1BMEdDU3FHU0liM0RRRUJCUVVBQTRJ
32
+ QkFRQkNReVJKTFhzQm8yRnkKOFc2ZS9XNFJlbVFScmxBdzlESzVPNlU3MUp0
33
+ ZWRWb2Iyb3ErT2Irem1TK1BpZkUyK0wrM1JpSjJINlZUbE96aQp4K0EwNjFN
34
+ VVhoR3JhcVZxNEoyRkM4a3Q0RVF5d0FEMFAwVGE1R1UyNENHU0YwOFkzR2tK
35
+ eTFTYTRYcVRDMllDCm81MXM3SlArdGtDQ3RwVllTZHpKaFRsbGllUkFXQnBH
36
+ VjFkdGFvZVVLRTZ0WVBNQmtvc3hTUmNWR2N6ay9TYzMKN2VRQ3BleFl5OUps
37
+ VUJJOXUzQnFJWTlFK2wrTVNuOGloWFNQbXlLMERncmhhQ3Urdm9hU0ZWT1g2
38
+ WStCNXFibwpqTFhNUXUyWmdJU1l3WE5qTmJHVkhlaHV0ODJVN1U5b2lIb1dj
39
+ ck9HYXphUlVtR085VFhQK2FKTEgwZ3cyZGNLCkFmTWdsWFBpCi0tLS0tRU5E
40
+ IENFUlRJRklDQVRFLS0tLS0K
41
+ date: 2013-06-02 00:00:00.000000000 Z
42
+ dependencies:
43
+ - !ruby/object:Gem::Dependency
44
+ name: json
45
+ requirement: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: 1.4.3
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: 1.4.3
59
+ - !ruby/object:Gem::Dependency
60
+ name: bundler
61
+ requirement: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: '1.3'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ version: '1.3'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ! '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ description: Extends Structs, Hashes, and Arrays with .to_json, .to_xml, and .to_s. This
92
+ handles nested data structures and some oddities that other methods do not.
93
+ email:
94
+ - rubygems@chrislee.dhs.org
95
+ executables: []
96
+ extensions: []
97
+ extra_rdoc_files: []
98
+ files:
99
+ - .gitignore
100
+ - Gemfile
101
+ - LICENSE.txt
102
+ - README.md
103
+ - Rakefile
104
+ - lib/structformatter.rb
105
+ - lib/structformatter/version.rb
106
+ - structformatter.gemspec
107
+ - test/helper.rb
108
+ - test/test_structformatter.rb
109
+ homepage: https://github.com/chrislee35/structformatter
110
+ licenses:
111
+ - MIT
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 1.8.25
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Extends Structs, Hashes, and Arrays with .to_json, .to_xml, and .to_s
134
+ test_files:
135
+ - test/helper.rb
136
+ - test/test_structformatter.rb
@@ -0,0 +1,4 @@
1
+ y��^1µblׅb��sm-Zckٙ�+vùw�6d�;�D߀,cZ�h�p_�Ѕ\#���)t�ɝ�<r(:�x�@Z��-H酇Po�se�e�tF�����nkk
2
+ ��K��d�4#
3
+ rd�XT�)�yJ+m��� d����aH�AI��cX
4
+ u�º�=9y�|���}ؠ�R���uZתK�{������y}o���U;P�x:(<�*��j����r䑏��Q�{:'b�SR z�DB�dml7U���