tjson 0.3.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3062690d7f47d6c5294c379941cc4638495879a6
4
- data.tar.gz: 7ff998fe639a348f1c4b3a15a8003c8246764014
3
+ metadata.gz: 5324e4ee4f01304e7330ed40c78c55eadfa8419e
4
+ data.tar.gz: 957686c2c7a4f589912a04e734b0aef2572621c7
5
5
  SHA512:
6
- metadata.gz: 5d6c02ed1b8bc9b78b79d6008ea9bc58d9f4ac82769a7ab6fd7e5c6acaad4ccdfb2259bb9e9dfaad7d19cae1e32b82834eefd7e9c10259259a4048f347867311
7
- data.tar.gz: bbaf0cc3b31ba54a020a9fd8985201040f3e64832d7d1bc53c648ebff667bfd3372ded56e7ce56adf90d9b088bae9cc7e58890f2d0e4e70aea2634293888dfa9
6
+ metadata.gz: 6f8ef3abc0f62a1f70ad46c285866c4d5847ec69c8112e0005d73564082c34d3d6c3b3c75f8b45bcaac8f9bb39eb14e23e281b88c9e46346abb6a54b5a2c3bf6
7
+ data.tar.gz: e020ee6c927f8ac48b17e00b09905ff7951ea50a5cfc65d1117d5d143b0f1ead6d291a9f86037cb1cae4d9a77b936b930d3796d553761f6cfa24c14f5009a59c
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build tjson-0.3.0.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Remove any temporary products" fullCmd="clean" taksId="clean" /><RakeTask description="Remove any generated files" fullCmd="clobber" taksId="clobber" /><RakeTask description="Build and install tjson-0.3.0.gem into system gems" fullCmd="install" taksId="install" /><RakeGroup description="" fullCmd="" taksId="install"><RakeTask description="Build and install tjson-0.3.0.gem into system gems without network access" fullCmd="install:local" taksId="local" /></RakeGroup><RakeTask description="Create tag v0.3.0 and build and push tjson-0.3.0.gem to Rubygems" fullCmd="release[remote]" taksId="release[remote]" /><RakeTask description="Run RuboCop" fullCmd="rubocop" taksId="rubocop" /><RakeGroup description="" fullCmd="" taksId="rubocop"><RakeTask description="Auto-correct RuboCop offenses" fullCmd="rubocop:auto_correct" taksId="auto_correct" /></RakeGroup><RakeTask description="Run RSpec code examples" fullCmd="spec" taksId="spec" /><RakeTask description="" fullCmd="default" taksId="default" /><RakeTask description="" fullCmd="release" taksId="release" /><RakeGroup description="" fullCmd="" taksId="release"><RakeTask description="" fullCmd="release:guard_clean" taksId="guard_clean" /><RakeTask description="" fullCmd="release:rubygem_push" taksId="rubygem_push" /><RakeTask description="" fullCmd="release:source_control_push" taksId="source_control_push" /></RakeGroup></RakeGroup></Settings>
@@ -1,16 +1,6 @@
1
1
  AllCops:
2
2
  DisplayCopNames: true
3
3
 
4
- #
5
- # Style
6
- #
7
-
8
- LineLength:
9
- Max: 128
10
-
11
- Style/StringLiterals:
12
- EnforcedStyle: double_quotes
13
-
14
4
  #
15
5
  # Metrics
16
6
  #
@@ -18,6 +8,9 @@ Style/StringLiterals:
18
8
  Metrics/AbcSize:
19
9
  Enabled: false
20
10
 
11
+ Metrics/BlockLength:
12
+ Max: 100
13
+
21
14
  Metrics/CyclomaticComplexity:
22
15
  Enabled: false
23
16
 
@@ -27,5 +20,24 @@ Metrics/PerceivedComplexity:
27
20
  Metrics/ClassLength:
28
21
  Max: 100
29
22
 
23
+ Metrics/LineLength:
24
+ Max: 128
25
+
30
26
  Metrics/MethodLength:
31
27
  Max: 25
28
+
29
+ #
30
+ # Performance
31
+ #
32
+
33
+ Performance/RegexpMatch:
34
+ Enabled: false
35
+
36
+ #
37
+ # Style
38
+ #
39
+
40
+ Style/StringLiterals:
41
+ EnforcedStyle: double_quotes
42
+
43
+
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.4.1
@@ -9,6 +9,7 @@ rvm:
9
9
  - 2.1
10
10
  - 2.2
11
11
  - 2.3.1
12
+ - 2.4.1
12
13
  - jruby-9.1.5.0
13
14
 
14
15
  matrix:
data/CHANGES.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.4.0 (2017-04-16)
2
+
3
+ * Add support for Boolean Value and Set types
4
+ * Add `TJSON.load` and `TJSON.load_file` methods
5
+
1
6
  ## 0.3.0 (2016-11-06)
2
7
 
3
8
  * Add `TJSON.pretty_generate`
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  source "https://rubygems.org"
4
+ ruby RUBY_VERSION
4
5
 
5
6
  gemspec
6
7
 
@@ -10,7 +11,7 @@ end
10
11
 
11
12
  group :development, :test do
12
13
  gem "rake"
13
- gem "toml-rb"
14
14
  gem "rspec", "~> 3.5"
15
- gem "rubocop", "0.44.1"
15
+ gem "rubocop", "0.48.1"
16
+ gem "toml-rb"
16
17
  end
data/Guardfile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # More info at https://github.com/guard/guard#readme
3
4
 
4
5
  guard :rspec, cmd: "GUARD_RSPEC=1 bundle exec rspec --no-profile" do
data/Rakefile CHANGED
@@ -8,4 +8,4 @@ RSpec::Core::RakeTask.new
8
8
  require "rubocop/rake_task"
9
9
  RuboCop::RakeTask.new
10
10
 
11
- task default: %w(spec rubocop)
11
+ task default: %w[spec rubocop]
@@ -3,7 +3,9 @@
3
3
  require "tjson/version"
4
4
 
5
5
  require "json"
6
+ require "set"
6
7
  require "time"
8
+
7
9
  require "base32"
8
10
  require "base64"
9
11
 
@@ -59,6 +61,19 @@ module TJSON
59
61
  object
60
62
  end
61
63
 
64
+ class << self
65
+ alias load parse
66
+ end
67
+
68
+ # Load data from a file containing TJSON
69
+ #
70
+ # @param filename [String] name of the .tjson file
71
+ # @raise [TJSON::ParseError] an error occurred parsing the given file
72
+ # @return [Object] parsed data
73
+ def self.load_file(filename)
74
+ load(File.read(filename))
75
+ end
76
+
62
77
  # Generate TJSON from a Ruby Hash (TJSON only allows objects as toplevel values)
63
78
  #
64
79
  # @param obj [Hash] Ruby Hash to serialize as TJSON
@@ -30,9 +30,12 @@ module TJSON
30
30
  case obj
31
31
  when Hash then self["O"]
32
32
  when ::Array then TJSON::DataType::Array.identify_type(obj)
33
+ when ::Set then TJSON::DataType::Set.identify_type(obj)
33
34
  when ::String, Symbol then obj.encoding == Encoding::BINARY ? self["b"] : self["s"]
34
35
  when ::Integer then self["i"]
35
36
  when ::Float then self["f"]
37
+ when ::TrueClass then self["v"]
38
+ when ::FalseClass then self["v"]
36
39
  when ::Time, ::DateTime then self["t"]
37
40
  else raise TypeError, "don't know how to serialize #{obj.class} as TJSON"
38
41
  end
@@ -42,6 +45,18 @@ module TJSON
42
45
  identify_type(obj).generate(obj)
43
46
  end
44
47
 
48
+ def tag
49
+ raise NotImplementError, "no #tag defined for #{self.class}"
50
+ end
51
+
52
+ def convert(_value)
53
+ raise NotImplementedError, "#{self.class} does not implement #convert"
54
+ end
55
+
56
+ def generate(_value)
57
+ raise NotImplementedError, "#{self.class} does not implement #genreate"
58
+ end
59
+
45
60
  # Scalar types
46
61
  class Scalar < TJSON::DataType
47
62
  def scalar?
@@ -83,9 +98,11 @@ require "tjson/datatype/array"
83
98
  require "tjson/datatype/binary"
84
99
  require "tjson/datatype/float"
85
100
  require "tjson/datatype/integer"
101
+ require "tjson/datatype/set"
86
102
  require "tjson/datatype/string"
87
103
  require "tjson/datatype/timestamp"
88
104
  require "tjson/datatype/object"
105
+ require "tjson/datatype/value"
89
106
 
90
107
  # TJSON does not presently support user-extensible types
91
108
  TJSON::DataType::TAGS = {
@@ -94,6 +111,7 @@ TJSON::DataType::TAGS = {
94
111
 
95
112
  # Non-scalars
96
113
  "A" => TJSON::DataType::Array,
114
+ "S" => TJSON::DataType::Set,
97
115
 
98
116
  # Scalars
99
117
  "b" => TJSON::DataType::Binary64.new.freeze,
@@ -104,5 +122,6 @@ TJSON::DataType::TAGS = {
104
122
  "i" => TJSON::DataType::SignedInt.new.freeze,
105
123
  "s" => TJSON::DataType::String.new.freeze,
106
124
  "t" => TJSON::DataType::Timestamp.new.freeze,
107
- "u" => TJSON::DataType::UnsignedInt.new.freeze
125
+ "u" => TJSON::DataType::UnsignedInt.new.freeze,
126
+ "v" => TJSON::DataType::Value.new.freeze
108
127
  }.freeze
@@ -9,7 +9,7 @@ module TJSON
9
9
  end
10
10
 
11
11
  def convert(float)
12
- raise TJSON::TypeError, "expected Float, got #{float.class}" unless float.is_a?(::Numeric)
12
+ raise TJSON::TypeError, "not a floating point value: #{float.inspect}" unless float.is_a?(::Numeric)
13
13
  float.to_f
14
14
  end
15
15
 
@@ -17,7 +17,7 @@ module TJSON
17
17
 
18
18
  def generate(obj)
19
19
  members = obj.map do |k, v|
20
- raise TypeError, "expected String for key, got #{k.class}" unless k.is_a?(::String)
20
+ raise TypeError, "expected String for key, got #{k.class}" unless k.is_a?(::String) || k.is_a?(Symbol)
21
21
  type = TJSON::DataType.identify_type(v)
22
22
  ["#{k}:#{type.tag}", TJSON::DataType.generate(v)]
23
23
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TJSON
4
+ class DataType
5
+ # TJSON sets
6
+ class Set < NonScalar
7
+ # Determine the type of a Ruby array (for serialization)
8
+ def self.identify_type(array)
9
+ inner_type = nil
10
+
11
+ array.each do |elem|
12
+ t = TJSON::DataType.identify_type(elem)
13
+ inner_type ||= t
14
+ raise TJSON::TypeError, "set contains heterogenous types: #{array.inspect}" unless inner_type == t
15
+ end
16
+
17
+ new(inner_type)
18
+ end
19
+
20
+ def tag
21
+ "S<#{@inner_type.tag}>"
22
+ end
23
+
24
+ def convert(array)
25
+ raise TJSON::TypeError, "expected Array, got #{array.class}" unless array.is_a?(::Array)
26
+
27
+ if @inner_type
28
+ result = ::Set.new(array.map { |o| @inner_type.convert(o) })
29
+ raise TJSON::ParseError, "set contains duplicate items" if result.size < array.size
30
+ return result
31
+ end
32
+
33
+ return ::Set.new if array.empty?
34
+ raise TJSON::ParseError, "no inner type specified for non-empty set: #{array.inspect}"
35
+ end
36
+
37
+ def generate(set)
38
+ set.map { |o| TJSON::DataType.generate(o) }
39
+ end
40
+ end
41
+ end
42
+ end
@@ -4,13 +4,16 @@ module TJSON
4
4
  class DataType
5
5
  # RFC3339 timestamp (Z-normalized)
6
6
  class Timestamp < Scalar
7
+ # Regular expression for matching timestamps
8
+ TIMESTAMP_REGEX = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\z/
9
+
7
10
  def tag
8
11
  "t"
9
12
  end
10
13
 
11
14
  def convert(str)
12
15
  raise TJSON::TypeError, "expected String, got #{str.class}: #{str.inspect}" unless str.is_a?(::String)
13
- raise TJSON::ParseError, "invalid timestamp: #{str.inspect}" unless str =~ /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z\z/
16
+ raise TJSON::ParseError, "invalid timestamp: #{str.inspect}" unless str =~ TIMESTAMP_REGEX
14
17
 
15
18
  ::Time.iso8601(str)
16
19
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TJSON
4
+ class DataType
5
+ # Boolean Value
6
+ class Value < Scalar
7
+ def tag
8
+ "v"
9
+ end
10
+
11
+ def convert(value)
12
+ raise TJSON::TypeError, "'null' is expressly disallowed in TJSON" if value.nil?
13
+ raise TJSON::TypeError, "not a boolean value: #{value.inspect}" unless [true, false].include?(value)
14
+ value
15
+ end
16
+
17
+ def generate(value)
18
+ value
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TJSON
4
- VERSION = "0.3.0"
4
+ VERSION = "0.4.0"
5
5
  end
@@ -1,5 +1,6 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
+
3
4
  lib = File.expand_path("../lib", __FILE__)
4
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
6
  require "tjson/version"
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tjson
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-06 00:00:00.000000000 Z
11
+ date: 2017-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.13'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.13'
41
41
  description: A JSON-compatible serialization format with rich type annotations
@@ -45,11 +45,12 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - ".gitignore"
49
- - ".rspec"
50
- - ".rubocop.yml"
51
- - ".ruby-version"
52
- - ".travis.yml"
48
+ - .gitignore
49
+ - .rakeTasks
50
+ - .rspec
51
+ - .rubocop.yml
52
+ - .ruby-version
53
+ - .travis.yml
53
54
  - CHANGES.md
54
55
  - Gemfile
55
56
  - Guardfile
@@ -63,8 +64,10 @@ files:
63
64
  - lib/tjson/datatype/float.rb
64
65
  - lib/tjson/datatype/integer.rb
65
66
  - lib/tjson/datatype/object.rb
67
+ - lib/tjson/datatype/set.rb
66
68
  - lib/tjson/datatype/string.rb
67
69
  - lib/tjson/datatype/timestamp.rb
70
+ - lib/tjson/datatype/value.rb
68
71
  - lib/tjson/object.rb
69
72
  - lib/tjson/version.rb
70
73
  - tjson.gemspec
@@ -78,17 +81,17 @@ require_paths:
78
81
  - lib
79
82
  required_ruby_version: !ruby/object:Gem::Requirement
80
83
  requirements:
81
- - - ">="
84
+ - - '>='
82
85
  - !ruby/object:Gem::Version
83
86
  version: '2.0'
84
87
  required_rubygems_version: !ruby/object:Gem::Requirement
85
88
  requirements:
86
- - - ">="
89
+ - - '>='
87
90
  - !ruby/object:Gem::Version
88
91
  version: '0'
89
92
  requirements: []
90
93
  rubyforge_project:
91
- rubygems_version: 2.5.1
94
+ rubygems_version: 2.6.11
92
95
  signing_key:
93
96
  specification_version: 4
94
97
  summary: Tagged JSON with Rich Types