# This file contains implementations of ruby core's custom objects for # serialisation/deserialisation. unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED require 'json' end require 'date' # Symbol serialization/deserialization class Symbol # Stores class name (Symbol) with String representation of Symbol as a JSON string. def to_json(*a) { JSON.create_id => self.class.name, 's' => to_s, }.to_json(*a) end # Deserializes JSON string by converting the string value stored in the object to a Symbol def self.json_create(o) o['s'].to_sym end end # Time serialization/deserialization class Time # Deserializes JSON string by converting time since epoch to Time def self.json_create(object) if usec = object.delete('u') # used to be tv_usec -> tv_nsec object['n'] = usec * 1000 end if respond_to?(:tv_nsec) at(*object.values_at('s', 'n')) else at(object['s'], object['n'] / 1000) end end # Stores class name (Time) with number of seconds since epoch and number of microseconds for Time as JSON string def to_json(*args) { JSON.create_id => self.class.name, 's' => tv_sec, 'n' => respond_to?(:tv_nsec) ? tv_nsec : tv_usec * 1000 }.to_json(*args) end end # Date serialization/deserialization class Date # Deserializes JSON string by converting Julian year y, month m, day d and Day of Calendar Reform sg to Date. def self.json_create(object) civil(*object.values_at('y', 'm', 'd', 'sg')) end alias start sg unless method_defined?(:start) # Stores class name (Date) with Julian year y, month m, day d and Day of Calendar Reform sg as JSON string def to_json(*args) { JSON.create_id => self.class.name, 'y' => year, 'm' => month, 'd' => day, 'sg' => start, }.to_json(*args) end end # DateTime serialization/deserialization class DateTime # Deserializes JSON string by converting year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg to DateTime. def self.json_create(object) args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') of_a, of_b = object['of'].split('/') if of_b and of_b != '0' args << Rational(of_a.to_i, of_b.to_i) else args << of_a end args << object['sg'] civil(*args) end alias start sg unless method_defined?(:start) # Stores class name (DateTime) with Julian year y, month m, day d, hour H, minute M, second S, offset of and Day of Calendar Reform sg as JSON string def to_json(*args) { JSON.create_id => self.class.name, 'y' => year, 'm' => month, 'd' => day, 'H' => hour, 'M' => min, 'S' => sec, 'of' => offset.to_s, 'sg' => start, }.to_json(*args) end end # Range serialization/deserialization class Range # Deserializes JSON string by constructing new Range object with arguments a serialized by to_json. def self.json_create(object) new(*object['a']) end # Stores class name (Range) with JSON array of arguments a which include first (integer), last (integer), and exclude_end? (boolean) as JSON string. def to_json(*args) { JSON.create_id => self.class.name, 'a' => [ first, last, exclude_end? ] }.to_json(*args) end end # Struct serialization/deserialization class Struct # Deserializes JSON string by constructing new Struct object with values v serialized by to_json. def self.json_create(object) new(*object['v']) end # Stores class name (Struct) with Struct values v as a JSON string. Only named structs are supported. def to_json(*args) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" { JSON.create_id => klass, 'v' => values, }.to_json(*args) end end # Exception serialization/deserialization class Exception # Deserializes JSON string by constructing new Exception object with message m and backtrace b serialized with to_json def self.json_create(object) result = new(object['m']) result.set_backtrace object['b'] result end # Stores class name (Exception) with message m and backtrace array b as JSON string def to_json(*args) { JSON.create_id => self.class.name, 'm' => message, 'b' => backtrace, }.to_json(*args) end end # Regexp serialization/deserialization class Regexp # Deserializes JSON string by constructing new Regexp object with source s (Regexp or String) and options o serialized by to_json def self.json_create(object) new(object['s'], object['o']) end # Stores class name (Regexp) with options o and source s (Regexp or String) as JSON string def to_json(*) { JSON.create_id => self.class.name, 'o' => options, 's' => source, }.to_json end end