Blame view

lib/syspro/syspro_object.rb 2.15 KB
db76748d   Isaac Lewis   cop a bunch of St...
1
2
  module Syspro
    class SysproObject
3d0157a5   Isaac Lewis   add logoff
3
      include Enumerable
db76748d   Isaac Lewis   cop a bunch of St...
4
  
3d0157a5   Isaac Lewis   add logoff
5
      def initialize(id = nil, opts = {})
db76748d   Isaac Lewis   cop a bunch of St...
6
        @opts = Util.normalize_opts(opts)
0c0af54a   Isaac Lewis   error handling; c...
7
8
9
10
11
12
13
14
        @original_values = {}
        @values = {}
  
        # This really belongs in APIResource, but not putting it there allows us
        # to have a unified inspect method
        @unsaved_values = Set.new
        @transient_values = Set.new
        @values[:id] = id if id
3d0157a5   Isaac Lewis   add logoff
15
      end
db76748d   Isaac Lewis   cop a bunch of St...
16
  
3d0157a5   Isaac Lewis   add logoff
17
18
19
20
21
22
      # Determines the equality of two Syspro objects. Syspro objects are
      # considered to be equal if they have the same set of values and each one
      # of those values is the same.
      def ==(other)
        other.is_a?(SysproObject) && @values == other.instance_variable_get(:@values)
      end
db76748d   Isaac Lewis   cop a bunch of St...
23
  
3d0157a5   Isaac Lewis   add logoff
24
25
26
      def to_s(*_args)
        JSON.pretty_generate(to_hash)
      end
db76748d   Isaac Lewis   cop a bunch of St...
27
  
3d0157a5   Isaac Lewis   add logoff
28
29
30
31
      def inspect
        id_string = respond_to?(:id) && !id.nil? ? " id=#{id}" : ""
        "#<#{self.class}:0x#{object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
      end
db76748d   Isaac Lewis   cop a bunch of St...
32
  
3d0157a5   Isaac Lewis   add logoff
33
34
      def keys
        @values.keys
db76748d   Isaac Lewis   cop a bunch of St...
35
36
      end
  
3d0157a5   Isaac Lewis   add logoff
37
38
39
      def values
        @values.values
      end
db76748d   Isaac Lewis   cop a bunch of St...
40
  
3d0157a5   Isaac Lewis   add logoff
41
42
43
44
      def to_hash
        maybe_to_hash = lambda do |value|
          value && value.respond_to?(:to_hash) ? value.to_hash : value
        end
db76748d   Isaac Lewis   cop a bunch of St...
45
  
3d0157a5   Isaac Lewis   add logoff
46
47
48
49
50
51
52
        @values.each_with_object({}) do |(key, value), acc|
          acc[key] = case value
                     when Array
                       value.map(&maybe_to_hash)
                     else
                       maybe_to_hash.call(value)
                     end
db76748d   Isaac Lewis   cop a bunch of St...
53
54
55
        end
      end
  
3d0157a5   Isaac Lewis   add logoff
56
57
58
      def each(&blk)
        @values.each(&blk)
      end
db76748d   Isaac Lewis   cop a bunch of St...
59
  
3d0157a5   Isaac Lewis   add logoff
60
61
62
      private
  
      # Produces a deep copy of the given object including support for arrays,
0c0af54a   Isaac Lewis   error handling; c...
63
      # hashes, and SysproObjects.
3d0157a5   Isaac Lewis   add logoff
64
65
66
67
68
69
70
71
      def self.deep_copy(obj)
        case obj
        when Array
          obj.map { |e| deep_copy(e) }
        when Hash
          obj.each_with_object({}) do |(k, v), copy|
            copy[k] = deep_copy(v)
            copy
db76748d   Isaac Lewis   cop a bunch of St...
72
          end
3d0157a5   Isaac Lewis   add logoff
73
74
75
76
77
78
79
80
81
        when SysproObject
          obj.class.construct_from(
            deep_copy(obj.instance_variable_get(:@values)),
            obj.instance_variable_get(:@opts).select do |k, _v|
              Util::OPTS_COPYABLE.include?(k)
            end
          )
        else
          obj
db76748d   Isaac Lewis   cop a bunch of St...
82
83
        end
      end
3d0157a5   Isaac Lewis   add logoff
84
85
      private_class_method :deep_copy
  
db76748d   Isaac Lewis   cop a bunch of St...
86
87
    end
  end