hashtostruct 0.9.0

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,4 @@
1
+ == 0.9.0 2008-11-29
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
@@ -0,0 +1,12 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/hashtostruct.rb
6
+ script/console
7
+ script/destroy
8
+ script/generate
9
+ spec/hashtostruct_spec.rb
10
+ spec/spec.opts
11
+ spec/spec_helper.rb
12
+ tasks/rspec.rake
@@ -0,0 +1,59 @@
1
+ = hashtostruct
2
+
3
+ http://github.com/openback/hashtostruct
4
+
5
+ == DESCRIPTION:
6
+
7
+ Takes a Hash and converts it into a Struct with each key as a property and
8
+ each value converted into a native object if possible.
9
+
10
+ == SYNOPSIS:
11
+
12
+ obj = {
13
+ "string" => "text nonsense",
14
+ "int" => "45",
15
+ "exp" => "123.45e1",
16
+ "date" => "2008-10-26 12:49:45",
17
+ "array" => [ "item_1", "45.2", "123e1" ],
18
+ "nested" => {
19
+ "int" => "32",
20
+ "string" => "textie"
21
+ }
22
+ }.to_struct
23
+
24
+ obj.int === 45
25
+ obj.date.year === 2008
26
+ obj.array[2] === 1230.0
27
+
28
+ == INSTALL:
29
+
30
+ sudo gem install hashtostruct
31
+
32
+ or from GitHub:
33
+
34
+ sudo gem install openback-hashtostruct
35
+
36
+ == LICENSE:
37
+
38
+ (The MIT License)
39
+
40
+ Copyright (c) 2008 Timmothy Caraballo
41
+
42
+ Permission is hereby granted, free of charge, to any person obtaining
43
+ a copy of this software and associated documentation files (the
44
+ 'Software'), to deal in the Software without restriction, including
45
+ without limitation the rights to use, copy, modify, merge, publish,
46
+ distribute, sublicense, and/or sell copies of the Software, and to
47
+ permit persons to whom the Software is furnished to do so, subject to
48
+ the following conditions:
49
+
50
+ The above copyright notice and this permission notice shall be
51
+ included in all copies or substantial portions of the Software.
52
+
53
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
54
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
57
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
58
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
59
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,26 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/hashtostruct'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('hashtostruct', Hashtostruct::VERSION) do |p|
7
+ p.developer('Timothy Caraballo', 'openback@gmail.com')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.rubyforge_name = p.name
10
+ # p.extra_deps = [
11
+ # ['activesupport','>= 2.0.2'],
12
+ # ]
13
+ p.extra_dev_deps = [
14
+ ['newgem', ">= #{::Newgem::VERSION}"]
15
+ ]
16
+
17
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
18
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
19
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
20
+ p.rsync_args = '-av --delete --ignore-errors'
21
+ end
22
+
23
+ require 'newgem/tasks' # load /tasks/*.rake
24
+ Dir['tasks/**/*.rake'].each { |t| load t }
25
+
26
+ task :default => [:spec]
@@ -0,0 +1,84 @@
1
+ require 'date'
2
+
3
+ module Hashtostruct
4
+ VERSION = '0.9.0'
5
+
6
+ module StringToObject
7
+ # Attempt to parse the string into a native Ruby object using standard formats
8
+ #
9
+ # It currently looks for and converts:
10
+ # * integers
11
+ # * floats
12
+ # * exponents into floats
13
+ # * booleans
14
+ # * DateTimes in the formats:
15
+ # * yyyy-mm-dd
16
+ # * yyyy-mm-dd hh:mm:ss
17
+ # * hh:mm
18
+ # * hh:mm:ss
19
+ # * hh:mm:ssZ
20
+ # * hh:mm:ss.ss
21
+ # * hh:mm:ss(+-)hh:mm
22
+ # * hh:mm:ss(+-)hhmm
23
+ # * hh:mm:ss(+-)hh
24
+ def to_obj
25
+ case self
26
+ when /^(tru|fals)e$/
27
+ self == 'true'
28
+ when /^[+-]?\d+$/
29
+ self.to_i
30
+ when /^[+-]?\d+\.\d+$/ # floats
31
+ self.to_f
32
+ when /^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/ # exponents
33
+ self.to_f
34
+ when /^(null|nil)$/
35
+ nil
36
+ when /^\d{2}:\d{2}(:\d{2}(\.\d+)?)?Z?$/
37
+ DateTime.parse(self)
38
+ when /^\d{2}:\d{2}:\d{2}[+-]\d{2}(:?\d{2})?$/
39
+ DateTime.parse(self)
40
+ when /^\d{4}-\d{2}-\d{2}$/
41
+ DateTime.parse(self)
42
+ when /^\d{4}-\d{2}-\d{2}[+-]\d{2}(:?\d{2})?$/
43
+ DateTime.parse(self)
44
+ when /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/
45
+ DateTime.parse(self)
46
+ else
47
+ self
48
+ end
49
+ end
50
+ end
51
+
52
+ module ArrayToObject
53
+ # iterates through the array, converting each string element to a native
54
+ # element if possible and returns it
55
+ def to_obj
56
+ self.inject([]) do |res,elem|
57
+ res << if elem.is_a?(String) or elem.is_a?(Array) or elem.is_a?(Hash)
58
+ elem.to_obj
59
+ else
60
+ elem
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ module HashToStruct
67
+ # Takes a Hash and converts it into a Struct with each key as a property
68
+ # each value converted into a native object if possible.
69
+ def to_struct
70
+ hash = self
71
+ Struct.new(*(hash.inject([]) { |res,val| res << val[0].to_sym })).new(*(
72
+ hash.inject([]) { |res,val| res << val[1].to_obj}
73
+ ))
74
+ end
75
+
76
+ def to_obj
77
+ to_struct
78
+ end
79
+ end
80
+
81
+ Array.send :include, ArrayToObject
82
+ String.send :include, StringToObject
83
+ Hash.send :include, HashToStruct
84
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/hashtostruct.rb'}"
9
+ puts "Loading hashtostruct gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,197 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Hashtostruct do
4
+ before(:each) do
5
+ @obj = {
6
+ "string" => "text nonsense",
7
+ "int" => "45",
8
+ "negative_int" => "-45",
9
+ "float" => "45.4",
10
+ "exp" => "123.45e1",
11
+ "null" => "null",
12
+ "nil" => "nil",
13
+ "capital_exp" => "123.45E1",
14
+ "negative_exp" => "-123.45e-1",
15
+ "capital_negative_exp" => "-123.45E-1",
16
+ "true" => "true",
17
+ "false" => "false",
18
+ "date1" => "2008-10-26 12:49:45",
19
+ "date2" => "2008-10-26",
20
+ "date3" => "2008-10",
21
+ "time1" => "12:49:45",
22
+ "time2" => "12:49:45Z",
23
+ "time3" => "12:49",
24
+ "time4" => "12:49:45.55",
25
+ "time5" => "12:49:45+03:00",
26
+ "time6" => "12:49:45+0300",
27
+ "time7" => "12:49:45+03",
28
+ "time8" => "12:49:45-03:00",
29
+ "time9" => "12:49:45-0300",
30
+ "time10" => "12:49:45-03",
31
+ "array" => [ "item_1", "45.2", "123e1" ],
32
+ "nested" => {
33
+ "int" => "32",
34
+ "string" => "textie"
35
+ }
36
+ }.to_struct
37
+ end
38
+
39
+ it "should add #to_struct to Hash" do
40
+ Hash.new.should respond_to('to_struct')
41
+ end
42
+
43
+ it "should create an object with specified properties" do
44
+ @obj.should respond_to('string')
45
+ @obj.should respond_to('float')
46
+ end
47
+
48
+ it "should set the value as a string" do
49
+ @obj.string.should eql('text nonsense')
50
+ end
51
+
52
+ it "should set the value as an integer" do
53
+ @obj.int.should eql(45)
54
+ @obj.negative_int.should eql(-45)
55
+ end
56
+
57
+ it "should set the value as float" do
58
+ @obj.float.should eql(45.4)
59
+ end
60
+
61
+ it "should set allow exponential values" do
62
+ @obj.exp.should eql(1234.5)
63
+ @obj.negative_exp.should eql(-12.345)
64
+ end
65
+
66
+ it "should set allow exponential values with capitals" do
67
+ @obj.capital_exp.should eql(1234.5)
68
+ @obj.capital_negative_exp.should eql(-12.345)
69
+ end
70
+
71
+ it "should parse 'yyyy-mm-dd' as Date" do
72
+ @obj.date2.should be_an_instance_of(DateTime)
73
+ @obj.date2.year.should eql(2008)
74
+ @obj.date2.month.should eql(10)
75
+ @obj.date2.day.should eql(26)
76
+ end
77
+
78
+ it "should parse 'yyyy-mm' as Date" do
79
+ pending("should it default to the 1st of the month?") do
80
+ @obj.date3.should be_an_instance_of(DateTime)
81
+ @obj.date3.year.should eql(2008)
82
+ @obj.date3.month.should eql(10)
83
+ end
84
+ end
85
+
86
+ it "should parse 'hh:mm:ss' as Time" do
87
+ @obj.time1.should be_an_instance_of(DateTime)
88
+ @obj.time1.hour.should eql(12)
89
+ @obj.time1.min.should eql(49)
90
+ @obj.time1.sec.should eql(45)
91
+ end
92
+
93
+ it "should parse 'hh:mm:ssZ' as Time" do
94
+ @obj.time2.should be_an_instance_of(DateTime)
95
+ @obj.time2.hour.should eql(12)
96
+ @obj.time2.min.should eql(49)
97
+ @obj.time2.sec.should eql(45)
98
+ @obj.time2.zone.should eql('+00:00')
99
+ end
100
+
101
+ it "should parse 'hh:mm' as Time" do
102
+ @obj.time3.should be_an_instance_of(DateTime)
103
+ @obj.time3.hour.should eql(12)
104
+ @obj.time3.min.should eql(49)
105
+ end
106
+
107
+ it "should parse 'hh:mm:ss.ss' as Time" do
108
+ @obj.time4.should be_an_instance_of(DateTime)
109
+ @obj.time4.hour.should eql(12)
110
+ @obj.time4.min.should eql(49)
111
+ @obj.time4.sec.should eql(45)
112
+ pending("check fractional part of the second")do
113
+ @obj.time4.sec_fraction.to_f.should eql(0.55)
114
+ end
115
+ end
116
+
117
+ it "should parse 'hh:mm:ss+hh:mm' as Time" do
118
+ @obj.time5.should be_an_instance_of(DateTime)
119
+ @obj.time5.hour.should eql(12)
120
+ @obj.time5.min.should eql(49)
121
+ @obj.time5.sec.should eql(45)
122
+ @obj.time5.zone.should eql('+03:00')
123
+ end
124
+
125
+ it "should parse 'hh:mm:ss+hhmm' as Time" do
126
+ @obj.time6.should be_an_instance_of(DateTime)
127
+ @obj.time6.hour.should eql(12)
128
+ @obj.time6.min.should eql(49)
129
+ @obj.time6.sec.should eql(45)
130
+ @obj.time6.zone.should eql('+03:00')
131
+ end
132
+
133
+ it "should parse 'hh:mm:ss+hh' as Time" do
134
+ @obj.time7.should be_an_instance_of(DateTime)
135
+ @obj.time7.hour.should eql(12)
136
+ @obj.time7.min.should eql(49)
137
+ @obj.time7.sec.should eql(45)
138
+ @obj.time7.zone.should eql('+03:00')
139
+ end
140
+
141
+ it "should parse 'hh:mm:ss-hh:mm' as Time" do
142
+ @obj.time8.should be_an_instance_of(DateTime)
143
+ @obj.time8.hour.should eql(12)
144
+ @obj.time8.min.should eql(49)
145
+ @obj.time8.sec.should eql(45)
146
+ @obj.time8.zone.should eql('-03:00')
147
+ end
148
+
149
+ it "should parse 'hh:mm:ss-hhmm' as Time" do
150
+ @obj.time9.should be_an_instance_of(DateTime)
151
+ @obj.time9.hour.should eql(12)
152
+ @obj.time9.min.should eql(49)
153
+ @obj.time9.sec.should eql(45)
154
+ @obj.time9.zone.should eql('-03:00')
155
+ end
156
+
157
+ it "should parse 'hh:mm:ss-hh' as Time" do
158
+ @obj.time10.should be_an_instance_of(DateTime)
159
+ @obj.time10.hour.should eql(12)
160
+ @obj.time10.min.should eql(49)
161
+ @obj.time10.sec.should eql(45)
162
+ @obj.time10.zone.should eql('-03:00')
163
+ end
164
+
165
+ it "should parse 'yyyy-mm-dd hh:mm:ss' as DateTime" do
166
+ @obj.date1.should be_an_instance_of(DateTime)
167
+ @obj.date1.year.should eql(2008)
168
+ @obj.date1.month.should eql(10)
169
+ @obj.date1.day.should eql(26)
170
+ @obj.date1.hour.should eql(12)
171
+ @obj.date1.min.should eql(49)
172
+ @obj.date1.sec.should eql(45)
173
+ @obj.date1.zone.should eql('+00:00')
174
+ end
175
+
176
+ it "should properly parse booleans" do
177
+ @obj.true.should eql(true)
178
+ @obj.false.should eql(false )
179
+ end
180
+
181
+ it "should properly parse null" do
182
+ @obj.null.should eql(nil)
183
+ @obj.nil.should eql(nil)
184
+ end
185
+
186
+ it "should properly handle nested objects" do
187
+ @obj.nested.should respond_to("string")
188
+ @obj.nested.string.should eql("textie")
189
+ @obj.nested.should respond_to("int")
190
+ @obj.nested.int.should eql(32)
191
+ end
192
+
193
+ it "should properly parse arrays" do
194
+ @obj.array.should be_an_instance_of(Array)
195
+ @obj.array.should eql(["item_1", 45.2, 1230.0])
196
+ end
197
+ end
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,10 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
10
+ require 'hashtostruct'
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hashtostruct
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Timothy Caraballo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-29 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: newgem
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.1.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hoe
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ version:
35
+ description: Takes a Hash and converts it into a Struct with each key as a property and each value converted into a native object if possible.
36
+ email:
37
+ - openback@gmail.com
38
+ executables: []
39
+
40
+ extensions: []
41
+
42
+ extra_rdoc_files:
43
+ - History.txt
44
+ - Manifest.txt
45
+ - README.rdoc
46
+ files:
47
+ - History.txt
48
+ - Manifest.txt
49
+ - README.rdoc
50
+ - Rakefile
51
+ - lib/hashtostruct.rb
52
+ - script/console
53
+ - script/destroy
54
+ - script/generate
55
+ - spec/hashtostruct_spec.rb
56
+ - spec/spec.opts
57
+ - spec/spec_helper.rb
58
+ - tasks/rspec.rake
59
+ has_rdoc: true
60
+ homepage: http://github.com/openback/hashtostruct
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --main
64
+ - README.rdoc
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project: hashtostruct
82
+ rubygems_version: 1.3.0
83
+ signing_key:
84
+ specification_version: 2
85
+ summary: Takes a Hash and converts it into a Struct with each key as a property and each value converted into a native object if possible.
86
+ test_files: []
87
+