tjson 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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