/
set.rb
127 lines (103 loc) · 2.59 KB
/
set.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
module Recliner
module Properties
module Set#:nodoc:
extend ActiveSupport::Concern
included do
Recliner::Property.send(:include, PropertyWithSetDefault)
end
module ClassMethods
def Set(type)
@set_class_cache ||= {}
@set_class_cache[type] ||= begin
returning Class.new(Recliner::Set) do |klass|
klass.type = type
end
end
end
end
module PropertyWithSetDefault#:nodoc:
extend ActiveSupport::Concern
included do
alias_method_chain :default_value, :set
end
def default_value_with_set(instance)
result = default_value_without_set(instance)
if type.superclass == Recliner::Set
if default
result = type[*default]
else
result = type.new
end
end
result
end
end
end
end
class Set < Array
class_inheritable_accessor :type
class << self
def from_couch(array)
self[*array.map { |i| type.from_couch(i) }]
end
def inspect
if self == Set
super
else
"#<Set[#{type}]>"
end
end
def [](*values)
super(*values.map { |i| convert_value(i) })
end
end
def []=(index, value)
super(index, convert_value(value))
end
def +(other_array)
self.class[*super(other_array.map { |i| convert_value(i) })]
end
def <<(obj)
super(convert_value(obj))
end
def concat(other_array)
super(other_array.map { |i| convert_value(i) })
end
def delete(obj)
super(convert_value(obj))
end
def index(obj)
super(convert_value(obj))
end
def insert(index, obj)
super(index, convert_value(obj))
end
def push(*values)
super(*values.map { |i| convert_value(i) })
end
def rindex(obj)
super(convert_value(obj))
end
def unshift(*values)
super(*values.map { |i| convert_value(i) })
end
private
def convert_value(value)
self.class.convert_value(value)
end
def self.convert_value(value)
return nil if value.nil?
if type == String
value.to_s
elsif type == Integer
value.to_i
elsif type == Float
value.to_f
elsif value.kind_of?(type)
value
else
raise TypeError, "expected #{type} but got #{value.class}"
end
end
end
end