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.
- checksums.yaml +7 -0
- data/lib/xon.rb +103 -0
- metadata +45 -0
checksums.yaml
ADDED
@@ -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
|
data/lib/xon.rb
ADDED
@@ -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: []
|