hashtostruct 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+