01b8e0412b0de532ca509f8dc270b9fbc2c3f9c5
[packages/precise/mcollective.git] / lib / mcollective / vendor / json / lib / json / add / core.rb
1 # This file contains implementations of ruby core's custom objects for
2 # serialisation/deserialisation.
3
4 unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
5   require 'json'
6 end
7 require 'date'
8
9 # Symbol serialization/deserialization
10 class Symbol
11   # Returns a hash, that will be turned into a JSON object and represent this
12   # object.
13   def as_json(*)
14     {
15       JSON.create_id => self.class.name,
16       's'            => to_s,
17     }
18   end
19
20   # Stores class name (Symbol) with String representation of Symbol as a JSON string.
21   def to_json(*a)
22     as_json.to_json(*a)
23   end
24
25   # Deserializes JSON string by converting the <tt>string</tt> value stored in the object to a Symbol
26   def self.json_create(o)
27     o['s'].to_sym
28   end
29 end
30
31 # Time serialization/deserialization
32 class Time
33
34   # Deserializes JSON string by converting time since epoch to Time
35   def self.json_create(object)
36     if usec = object.delete('u') # used to be tv_usec -> tv_nsec
37       object['n'] = usec * 1000
38     end
39     if instance_methods.include?(:tv_nsec)
40       at(object['s'], Rational(object['n'], 1000))
41     else
42       at(object['s'], object['n'] / 1000)
43     end
44   end
45
46   # Returns a hash, that will be turned into a JSON object and represent this
47   # object.
48   def as_json(*)
49     nanoseconds = [ tv_usec * 1000 ]
50     respond_to?(:tv_nsec) and nanoseconds << tv_nsec
51     nanoseconds = nanoseconds.max
52     {
53       JSON.create_id => self.class.name,
54       's'            => tv_sec,
55       'n'            => nanoseconds,
56     }
57   end
58
59   # Stores class name (Time) with number of seconds since epoch and number of
60   # microseconds for Time as JSON string
61   def to_json(*args)
62     as_json.to_json(*args)
63   end
64 end
65
66 # Date serialization/deserialization
67 class Date
68
69   # Deserializes JSON string by converting Julian year <tt>y</tt>, month
70   # <tt>m</tt>, day <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> to Date.
71   def self.json_create(object)
72     civil(*object.values_at('y', 'm', 'd', 'sg'))
73   end
74
75   alias start sg unless method_defined?(:start)
76
77   # Returns a hash, that will be turned into a JSON object and represent this
78   # object.
79   def as_json(*)
80     {
81       JSON.create_id => self.class.name,
82       'y' => year,
83       'm' => month,
84       'd' => day,
85       'sg' => start,
86     }
87   end
88
89   # Stores class name (Date) with Julian year <tt>y</tt>, month <tt>m</tt>, day
90   # <tt>d</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
91   def to_json(*args)
92     as_json.to_json(*args)
93   end
94 end
95
96 # DateTime serialization/deserialization
97 class DateTime
98
99   # Deserializes JSON string by converting year <tt>y</tt>, month <tt>m</tt>,
100   # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
101   # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> to DateTime.
102   def self.json_create(object)
103     args = object.values_at('y', 'm', 'd', 'H', 'M', 'S')
104     of_a, of_b = object['of'].split('/')
105     if of_b and of_b != '0'
106       args << Rational(of_a.to_i, of_b.to_i)
107     else
108       args << of_a
109     end
110     args << object['sg']
111     civil(*args)
112   end
113
114   alias start sg unless method_defined?(:start)
115
116   # Returns a hash, that will be turned into a JSON object and represent this
117   # object.
118   def as_json(*)
119     {
120       JSON.create_id => self.class.name,
121       'y' => year,
122       'm' => month,
123       'd' => day,
124       'H' => hour,
125       'M' => min,
126       'S' => sec,
127       'of' => offset.to_s,
128       'sg' => start,
129     }
130   end
131
132   # Stores class name (DateTime) with Julian year <tt>y</tt>, month <tt>m</tt>,
133   # day <tt>d</tt>, hour <tt>H</tt>, minute <tt>M</tt>, second <tt>S</tt>,
134   # offset <tt>of</tt> and Day of Calendar Reform <tt>sg</tt> as JSON string
135   def to_json(*args)
136     as_json.to_json(*args)
137   end
138 end
139
140 # Range serialization/deserialization
141 class Range
142
143   # Deserializes JSON string by constructing new Range object with arguments
144   # <tt>a</tt> serialized by <tt>to_json</tt>.
145   def self.json_create(object)
146     new(*object['a'])
147   end
148
149   # Returns a hash, that will be turned into a JSON object and represent this
150   # object.
151   def as_json(*)
152     {
153       JSON.create_id  => self.class.name,
154       'a'             => [ first, last, exclude_end? ]
155     }
156   end
157
158   # Stores class name (Range) with JSON array of arguments <tt>a</tt> which
159   # include <tt>first</tt> (integer), <tt>last</tt> (integer), and
160   # <tt>exclude_end?</tt> (boolean) as JSON string.
161   def to_json(*args)
162     as_json.to_json(*args)
163   end
164 end
165
166 # Struct serialization/deserialization
167 class Struct
168
169   # Deserializes JSON string by constructing new Struct object with values
170   # <tt>v</tt> serialized by <tt>to_json</tt>.
171   def self.json_create(object)
172     new(*object['v'])
173   end
174
175   # Returns a hash, that will be turned into a JSON object and represent this
176   # object.
177   def as_json(*)
178     klass = self.class.name
179     klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
180     {
181       JSON.create_id => klass,
182       'v'            => values,
183     }
184   end
185
186   # Stores class name (Struct) with Struct values <tt>v</tt> as a JSON string.
187   # Only named structs are supported.
188   def to_json(*args)
189     as_json.to_json(*args)
190   end
191 end
192
193 # Exception serialization/deserialization
194 class Exception
195
196   # Deserializes JSON string by constructing new Exception object with message
197   # <tt>m</tt> and backtrace <tt>b</tt> serialized with <tt>to_json</tt>
198   def self.json_create(object)
199     result = new(object['m'])
200     result.set_backtrace object['b']
201     result
202   end
203
204   # Returns a hash, that will be turned into a JSON object and represent this
205   # object.
206   def as_json(*)
207     {
208       JSON.create_id => self.class.name,
209       'm'            => message,
210       'b'            => backtrace,
211     }
212   end
213
214   # Stores class name (Exception) with message <tt>m</tt> and backtrace array
215   # <tt>b</tt> as JSON string
216   def to_json(*args)
217     as_json.to_json(*args)
218   end
219 end
220
221 # Regexp serialization/deserialization
222 class Regexp
223
224   # Deserializes JSON string by constructing new Regexp object with source
225   # <tt>s</tt> (Regexp or String) and options <tt>o</tt> serialized by
226   # <tt>to_json</tt>
227   def self.json_create(object)
228     new(object['s'], object['o'])
229   end
230
231   # Returns a hash, that will be turned into a JSON object and represent this
232   # object.
233   def as_json(*)
234     {
235       JSON.create_id => self.class.name,
236       'o'            => options,
237       's'            => source,
238     }
239   end
240
241   # Stores class name (Regexp) with options <tt>o</tt> and source <tt>s</tt>
242   # (Regexp or String) as JSON string
243   def to_json(*)
244     as_json.to_json
245   end
246 end