xon 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/xon.rb +103 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bf21825f5fbaa93448dcb96234686181cc974d5d80c2c63f2b655f62399b54a9
4
+ data.tar.gz: e9baf76360bab8da9369498a92362c6b02df4b9f3eb075aa5f42d71852ad139a
5
+ SHA512:
6
+ metadata.gz: dfd2f9fbb2b7c6b512302cd4d7a4a9e1d72d954ab7b82b8a7584d0d13b4a2e0712c3ea2dc0307e67c64de1524fe0127d9bffee530e3ad2368ee3916d7fc3536a
7
+ data.tar.gz: c3873e88b34727d6df600e9ddc54ed66e2ed38481ae2c70299371fdf525ff21b67ab15329b86c5b6ff7579146a4c1b6ff39225fd1d486c8fbfa33128657926be
@@ -0,0 +1,103 @@
1
+ require 'time'
2
+ require 'json'
3
+
4
+ module Xon
5
+
6
+ class ParserError < StandardError; end
7
+
8
+ VERSION = '0.1.0'.freeze
9
+ PREAMBLE = '!:'.freeze
10
+
11
+ class << self
12
+
13
+ def parse(str)
14
+ init!
15
+ if str.is_a?(String) && str.start_with?(PREAMBLE)
16
+ decode(JSON.parse(str[PREAMBLE.length..-1]))
17
+ else
18
+ JSON.parse(str)
19
+ end
20
+ rescue JSON::ParserError => e
21
+ raise ParserError.new(e.message)
22
+ end
23
+
24
+ def generate(data)
25
+ init!
26
+ if special?(data)
27
+ PREAMBLE + JSON.generate(encode(data))
28
+ else
29
+ JSON.generate(data)
30
+ end
31
+ end
32
+
33
+ alias :load :parse
34
+ alias :dump :generate
35
+
36
+ private
37
+
38
+ def decode(obj)
39
+ if obj.is_a?(String)
40
+ type, value = obj.split(":", 2)
41
+ raise ParserError.new("incorrectly formatted string value") if value.nil?
42
+ case type
43
+ when ''
44
+ value
45
+ when 't'
46
+ begin
47
+ Time.parse(value)
48
+ rescue ArgumentError => e
49
+ raise ParserError.new(e.message)
50
+ end
51
+ else
52
+ raise ParserError.new("unknown type in string value")
53
+ end
54
+ elsif obj.is_a?(Array)
55
+ obj.map { |v| decode(v) }
56
+ elsif obj.is_a?(Hash)
57
+ obj.transform_values { |v| decode(v) }
58
+ else
59
+ obj
60
+ end
61
+ end
62
+
63
+ def encode(obj)
64
+ if obj.is_a?(String)
65
+ ":#{obj}"
66
+ elsif obj.is_a?(Time) || obj.is_a?(DateTime)
67
+ "t:#{obj.iso8601}"
68
+ elsif obj.is_a?(Array)
69
+ obj.map { |v| encode(v) }
70
+ elsif obj.is_a?(Hash)
71
+ obj.transform_values { |v| encode(v) }
72
+ else
73
+ obj
74
+ end
75
+ end
76
+
77
+ def special?(obj)
78
+ if obj.is_a?(Time) || obj.is_a?(DateTime)
79
+ true
80
+ elsif obj.is_a?(Array)
81
+ obj.any? { |v| special?(v) }
82
+ elsif obj.is_a?(Hash)
83
+ obj.values.any? { |v| special?(v) }
84
+ else
85
+ false
86
+ end
87
+ end
88
+
89
+ # This initialization of constants is intentionally not done in the body
90
+ # of the module, to not be sensitive to loading order.
91
+ @@inited = false
92
+ def init!
93
+ return if @@inited
94
+ @@inited = true
95
+ # Ignore DateTime gracefully if it is not loaded.
96
+ const_set(:DateTime, defined?(DateTime) ? DateTime : Class.new)
97
+ # Prefer MultiJson if it is loaded.
98
+ const_set(:JSON, defined?(MultiJson) ? MultiJson : JSON)
99
+ end
100
+
101
+ end
102
+
103
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Fouad Mardini
8
+ - Sinan Taifour
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-01 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: " Xon is a superset of JSON that supports Time values.\n"
15
+ email: code@bloometric.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/xon.rb
21
+ homepage:
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.7.6.2
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: 'Xon: A Superset of JSON'
45
+ test_files: []