omnistruct 1.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.
- checksums.yaml +7 -0
- data/README.md +70 -0
- data/ext/classystruct.rb +47 -0
- data/ext/hash.rb +105 -0
- data/ext/openstruct.rb +51 -0
- data/ext/struct.rb +52 -0
- data/omnistruct.rb +43 -0
- metadata +91 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f2bca86c8dfacd6cc38fa06c599593f19ab4ad67
|
4
|
+
data.tar.gz: 203817b49cdaf1f902cc88d98f451c0a545b856c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d91807ccee8ac5a7e9abf1b30c042795cfc75a9bce15fe8fbfebce09588984267723ea539795a16b956de9f2522148c936903b677fd5f83439a7a53dd818e7bb
|
7
|
+
data.tar.gz: b8b4ff5b8c5c2086986451948d72bf6f3f18ddb79683d3b55b1fca4650dfcf894a2628d0627022a13e041e832e0ce9279626c52274f997bc6af7e2b96e5570e5
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
OmniStruct - [](https://travis-ci.org/jmervine/omnistruct)
|
2
|
+
==========
|
3
|
+
|
4
|
+
Helpers for using OpenStruct and/or Struct over Hash
|
5
|
+
|
6
|
+
### Usage
|
7
|
+
|
8
|
+
Require after or in place of `classy_struct`, `ostruct` and/or `struct`.
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
# good
|
12
|
+
require 'omnistruct`
|
13
|
+
|
14
|
+
# also good
|
15
|
+
require 'ostruct`
|
16
|
+
require 'omnistruct`
|
17
|
+
|
18
|
+
# bad
|
19
|
+
require 'omnistruct`
|
20
|
+
require 'ostruct`
|
21
|
+
```
|
22
|
+
|
23
|
+
> TODO: document the following better
|
24
|
+
|
25
|
+
Add's the following methods to `Hash`;
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
# Hash
|
29
|
+
##
|
30
|
+
|
31
|
+
# class methods
|
32
|
+
Hash.struct_type
|
33
|
+
Hash.struct_type=
|
34
|
+
|
35
|
+
# instance methods
|
36
|
+
Hash.new.to_struct(type=Hash.struct_type)
|
37
|
+
```
|
38
|
+
|
39
|
+
Add's the following common `Hash` methods to struct types;
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
# All: ClassyStruct / OpenStruct / Struct
|
43
|
+
##
|
44
|
+
|
45
|
+
struct = <struct type>.to_struct( [type] )
|
46
|
+
merged = <struct type>.merge( Hash.new | <struct type> )
|
47
|
+
json = <struct type>.to_json
|
48
|
+
|
49
|
+
# ClassyStruct
|
50
|
+
locked = <classy struct>.lock
|
51
|
+
locked.class
|
52
|
+
# => "Struct"
|
53
|
+
|
54
|
+
# OpenStruct
|
55
|
+
OpenStruct.new.merge!( Hash.new | <struct type> )
|
56
|
+
|
57
|
+
locked = OpenStruct.new.lock
|
58
|
+
locked.class
|
59
|
+
# => "Struct"
|
60
|
+
|
61
|
+
# Struct
|
62
|
+
unlocked = <Struct>.unlock( [type] )
|
63
|
+
```
|
64
|
+
|
65
|
+
### Development
|
66
|
+
|
67
|
+
```
|
68
|
+
bundle install --path .bundle
|
69
|
+
bundle exec ruby ./test.rb
|
70
|
+
```
|
data/ext/classystruct.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'hash')
|
2
|
+
require 'classy_struct'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
# ClassyStruct patches
|
6
|
+
####
|
7
|
+
class ClassyStruct
|
8
|
+
class ClassyStructClass
|
9
|
+
alias :to_h :to_hash
|
10
|
+
|
11
|
+
# Convert ClassyStruct to Struct or OpenStruct
|
12
|
+
#
|
13
|
+
# Example:
|
14
|
+
#
|
15
|
+
# struct = { :foo => :bar }.to_struct(:classy_struct)
|
16
|
+
#
|
17
|
+
# # noop
|
18
|
+
# s = struct.to_struct
|
19
|
+
# s.class
|
20
|
+
# #=> ClassyHashStruct
|
21
|
+
#
|
22
|
+
# s = struct.to_struct(:struct)
|
23
|
+
# s.class
|
24
|
+
# #=> Struct
|
25
|
+
#
|
26
|
+
# s = struct.to_struct(:open_struct)
|
27
|
+
# s.class
|
28
|
+
# #=> OpenStruct
|
29
|
+
def to_struct(type=:classy_struct)
|
30
|
+
return self if type.to_sym == :classy_struct
|
31
|
+
return self.to_h.to_struct(type)
|
32
|
+
end
|
33
|
+
|
34
|
+
def merge other
|
35
|
+
self.to_h.merge!(other.to_h).to_struct(:classy_struct)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Convert ClassyStruct to Struct, thus locking it.
|
39
|
+
def lock
|
40
|
+
self.to_h.to_struct(:struct)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_json
|
44
|
+
self.to_h.to_json
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/ext/hash.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
# Supports converting Hashes in to different kinds of structs via a 'to_struct'
|
4
|
+
# method.
|
5
|
+
#
|
6
|
+
# Note: ClassyStruct perferred over OpenStruct, it's faster.
|
7
|
+
class Hash
|
8
|
+
CLASSY_STRUCT_NAME = "ClassyHashStruct"
|
9
|
+
|
10
|
+
attr_accessor :struct_type
|
11
|
+
@@struct_type = :classy_struct
|
12
|
+
|
13
|
+
# Convert Hash to Struct, OpenStruct or ClassyStruct
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# hash = { :foo => :bar }
|
18
|
+
#
|
19
|
+
# # default
|
20
|
+
# s = hash.to_struct(:classy_struct)
|
21
|
+
# s.class
|
22
|
+
# #=> ClassyHashStruct
|
23
|
+
# hash.foo
|
24
|
+
# #=> :bar
|
25
|
+
#
|
26
|
+
# s = hash.to_struct(:struct)
|
27
|
+
# s.class
|
28
|
+
# #=> Struct
|
29
|
+
#
|
30
|
+
# s = hash.to_struct(:open_struct)
|
31
|
+
# s.class
|
32
|
+
# #=> OpenStruct
|
33
|
+
def to_struct(type=nil)
|
34
|
+
self.struct_type = type.nil? ? struct_type : type.to_sym
|
35
|
+
|
36
|
+
if struct_type == :classy_struct
|
37
|
+
begin
|
38
|
+
Object.send(:remove_const, CLASSY_STRUCT_NAME.to_sym)
|
39
|
+
rescue; end
|
40
|
+
|
41
|
+
return Object.const_set(CLASSY_STRUCT_NAME, ClassyStruct.new).new(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
self.each do |k,v|
|
45
|
+
self[k] = v.to_struct(struct_type) if v.is_a? Hash
|
46
|
+
end
|
47
|
+
|
48
|
+
if struct_type == :open_struct
|
49
|
+
# openstruct is said to be slower, so giving the option to disable
|
50
|
+
return OpenStruct.new(self)
|
51
|
+
end
|
52
|
+
|
53
|
+
# otherwise use standard struct
|
54
|
+
return nil if self.empty?
|
55
|
+
|
56
|
+
klass = Struct.new(*keys.map{|key| key.to_sym})
|
57
|
+
klass.new(*values)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Return struct type for instance.
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
#
|
64
|
+
# hash = { :foo => :bar }
|
65
|
+
#
|
66
|
+
# # default
|
67
|
+
# hash.struct_type
|
68
|
+
# #=> :classy_struct
|
69
|
+
def struct_type
|
70
|
+
@struct_type || @@struct_type
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return struct type for class.
|
74
|
+
#
|
75
|
+
# Example:
|
76
|
+
#
|
77
|
+
# Hash.struct_type
|
78
|
+
# #=> :classy_struct
|
79
|
+
#
|
80
|
+
def self.struct_type
|
81
|
+
@@struct_type
|
82
|
+
end
|
83
|
+
|
84
|
+
# Set struct type for class.
|
85
|
+
#
|
86
|
+
# Example:
|
87
|
+
#
|
88
|
+
# Hash.struct_type = :struct
|
89
|
+
# Hash.struct_type
|
90
|
+
# #=> :struct
|
91
|
+
# hash = { :foo => :bar }
|
92
|
+
# hash.struct_type
|
93
|
+
# #=> :struct
|
94
|
+
def self.struct_type= type
|
95
|
+
type = type.to_sym
|
96
|
+
raise "Invalid struct type: #{type}." unless struct_types.include?(type)
|
97
|
+
|
98
|
+
@@struct_type = type.to_sym
|
99
|
+
end
|
100
|
+
|
101
|
+
protected
|
102
|
+
def self.struct_types
|
103
|
+
[ :classy_struct, :open_struct, :struct ]
|
104
|
+
end
|
105
|
+
end
|
data/ext/openstruct.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'hash')
|
2
|
+
require 'ostruct'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class OpenStruct
|
6
|
+
# replaces object
|
7
|
+
def merge! other
|
8
|
+
self.marshal_load(merge(other).to_h)
|
9
|
+
end
|
10
|
+
|
11
|
+
# returns new object
|
12
|
+
def merge other
|
13
|
+
OpenStruct.new(self.marshal_dump.merge(other.to_h))
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_json
|
17
|
+
self.marshal_dump.to_json
|
18
|
+
end
|
19
|
+
|
20
|
+
# Convert OpenStruct to Struct, thus locking it.
|
21
|
+
def lock
|
22
|
+
self.marshal_dump.to_struct(:struct)
|
23
|
+
end
|
24
|
+
|
25
|
+
def unlock
|
26
|
+
self # noop
|
27
|
+
end
|
28
|
+
|
29
|
+
# Convert OpenStruct to Struct or ClassyStruct
|
30
|
+
#
|
31
|
+
# Example:
|
32
|
+
#
|
33
|
+
# struct = { :foo => :bar }.to_struct(:classy_struct)
|
34
|
+
#
|
35
|
+
# # noop
|
36
|
+
# s = struct.to_struct
|
37
|
+
# s.class
|
38
|
+
# #=> OpenStruct
|
39
|
+
#
|
40
|
+
# s = struct.to_struct(:struct)
|
41
|
+
# s.class
|
42
|
+
# #=> Struct
|
43
|
+
#
|
44
|
+
# s = struct.to_struct(:classy_struct)
|
45
|
+
# s.class
|
46
|
+
# #=> ClassyHashStruct
|
47
|
+
def to_struct(type=:open_struct)
|
48
|
+
return self if type.to_sym == :open_struct
|
49
|
+
return self.marshal_dump.to_struct(type)
|
50
|
+
end
|
51
|
+
end
|
data/ext/struct.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'hash')
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class Struct
|
5
|
+
# returns new object
|
6
|
+
def merge other
|
7
|
+
selfHash = self.to_h
|
8
|
+
otherHash = other.is_a?(Hash) ? other : other.to_h
|
9
|
+
|
10
|
+
selfHash.merge!(otherHash)
|
11
|
+
selfHash.to_struct(:struct)
|
12
|
+
end
|
13
|
+
|
14
|
+
def lock
|
15
|
+
self #noop
|
16
|
+
end
|
17
|
+
|
18
|
+
# Convert Struct to OpenStruct or ClassyStruct (default), thus unlocking it.
|
19
|
+
def unlock(type=:classy_struct)
|
20
|
+
return nil if type.to_sym == :struct
|
21
|
+
return self.to_h.to_struct(type)
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_json
|
25
|
+
self.to_h.to_json
|
26
|
+
end
|
27
|
+
|
28
|
+
# Convert Struct # to OpenStruct or ClassyStruct
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
#
|
32
|
+
# struct = { :foo => :bar }.to_struct(:struct)
|
33
|
+
#
|
34
|
+
# # noop
|
35
|
+
# s = struct.to_struct
|
36
|
+
# s.class
|
37
|
+
# #=> Struct
|
38
|
+
#
|
39
|
+
# s = struct.to_struct(:open_struct)
|
40
|
+
# s.class
|
41
|
+
# #=> OpenStruct
|
42
|
+
#
|
43
|
+
# s = struct.to_struct(:classy_struct)
|
44
|
+
# s.class
|
45
|
+
# #=> ClassyHashStruct
|
46
|
+
def to_struct(type=:classy_struct)
|
47
|
+
return self if type.to_sym == :struct
|
48
|
+
return self.to_h.to_struct(type)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
data/omnistruct.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'ext', '*.rb')).each do |lib|
|
2
|
+
require lib
|
3
|
+
end
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# Top level class, mainly for correct requiring, but wraps Hash extensions as
|
7
|
+
# well.
|
8
|
+
module OmniStruct
|
9
|
+
# Wraps Hash.to_struct
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
#
|
13
|
+
# s = OmniStruct.new({:foo => :bar})
|
14
|
+
# s.class
|
15
|
+
# #=> ClassyHashStruct
|
16
|
+
# s.foo
|
17
|
+
# #=> :bar
|
18
|
+
#
|
19
|
+
# s = OmniStruct.new({:foo => :bar})
|
20
|
+
# s.class
|
21
|
+
# #=> ClassyHashStruct
|
22
|
+
# s.foo
|
23
|
+
# #=> :bar
|
24
|
+
def self.new hash=Hash.new, type=Hash.struct_type
|
25
|
+
return hash.to_struct(type)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Wraps Hash.struct_type
|
29
|
+
def self.struct_type
|
30
|
+
Hash.struct_type
|
31
|
+
end
|
32
|
+
|
33
|
+
# Wraps Hash.struct_type=
|
34
|
+
def self.struct_type= type
|
35
|
+
Hash.struct_type = type
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
# Wraps Hash.struct_types
|
40
|
+
def self.struct_types
|
41
|
+
Hash.send(:struct_types)
|
42
|
+
end
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omnistruct
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joshua Mervine
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: classy_struct
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.3'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.3.2
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.3'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.3.2
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: minitest
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.4'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 5.4.3
|
43
|
+
type: :development
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '5.4'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 5.4.3
|
53
|
+
description: 'OmniStruct: Struct Utilities -- Helpers for ClassyStruct, OpenStruct
|
54
|
+
and Struct'
|
55
|
+
email:
|
56
|
+
- joshua@mervine.net
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- README.md
|
62
|
+
- ext/classystruct.rb
|
63
|
+
- ext/hash.rb
|
64
|
+
- ext/openstruct.rb
|
65
|
+
- ext/struct.rb
|
66
|
+
- omnistruct.rb
|
67
|
+
homepage: https://github.com/jmervine/omnistruct
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- "."
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.2.2
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: 'OmniStruct: Struct Utilities'
|
91
|
+
test_files: []
|