1require 'ostruct'
2
3module JSON
4  class GenericObject < OpenStruct
5    class << self
6      alias [] new
7
8      def json_creatable?
9        @json_creatable
10      end
11
12      attr_writer :json_creatable
13
14      def json_create(data)
15        data = data.dup
16        data.delete JSON.create_id
17        self[data]
18      end
19
20      def from_hash(object)
21        case
22        when object.respond_to?(:to_hash)
23          result = new
24          object.to_hash.each do |key, value|
25            result[key] = from_hash(value)
26          end
27          result
28        when object.respond_to?(:to_ary)
29          object.to_ary.map { |a| from_hash(a) }
30        else
31          object
32        end
33      end
34    end
35    self.json_creatable = false
36
37    def to_hash
38      table
39    end
40
41    def [](name)
42      table[name.to_sym]
43    end
44
45    def []=(name, value)
46      __send__ "#{name}=", value
47    end
48
49    def |(other)
50      self.class[other.to_hash.merge(to_hash)]
51    end
52
53    def as_json(*)
54      { JSON.create_id => self.class.name }.merge to_hash
55    end
56
57    def to_json(*a)
58      as_json.to_json(*a)
59    end
60  end
61end
62