omnistruct 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 - [![Build Status](https://travis-ci.org/jmervine/omnistruct.svg?branch=master)](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: []
|