nestedtext 0.6.0 → 1.0.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
  SHA256:
3
- metadata.gz: 8ffd37e7360f79d6b9bd1dec3ca7687ea16d5e44f3a8ff0286af9df02307b04b
4
- data.tar.gz: 6bd6979a011e1072cc9fea0e23b429792576b728b011d58efeb397d66dac809f
3
+ metadata.gz: 74caf2136f95b24dc7b72d92e869c59992e7a573258d50c33762ade211f289fc
4
+ data.tar.gz: 9a185f16e4ecf87166fd90e47487a1bbff690713479049503b8b63594889c296
5
5
  SHA512:
6
- metadata.gz: 951bb426600944496e51b96ce51b7315baec4c54e55bf78c67cc72db222a18a70a1a328e5c29d0a48764bdc3413fe0fd674f2f23e58e04a909a057ac3d8a5165
7
- data.tar.gz: b1cdc7c5f13b2e7846918e20707969e8cc636d4b3390622ce6914b6d785888b4319627af040a7bda95a4883c3818ae9bb83852b86d23262f325d5588bbe56191
6
+ metadata.gz: 49da0bd5404cc394f0ab0bf746da45fad947502bdb7c9a5017df44c5a7fff0bfc25a3b3baa3142574185fe8da727ddee388903f2cb0a3efbe683f952bdfd7a59
7
+ data.tar.gz: 66e5f06985d49b05702d6a569c1ac44f875726bd01ba7021b9e8ede0fb39e83aae9141e3c9e5e06c720e7dde207ac5b334c217473b0e36c390d3914c27eb5d83
data/CHANGELOG.md CHANGED
@@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.0.0] - 2022-01-25
10
+ The library is now useful for clients!
11
+
12
+ ### Changed
13
+ - Hide all internals in the module from clients.
14
+
9
15
  ## [0.6.0] - 2022-01-24
10
16
  ### Fixed
11
17
  - Move runtime dependencies from Gemfile to .gemspec.
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # NestedText Ruby Library [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Get%20a%20nifty%20tooltip%20for%20term%20definitions%20in%20your%20Jekyll%20blog%20with%20this%20plugin&url=https://github.com/erikw/nestedtext-ruby&via=erik_westrup&hashtags=jekyll,plugin)
1
+ # NestedText Ruby Library [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=NestedText,%20the%20human%20friendly%20data%20format,%20has%20a%20now%20a%20ruby%20library%20for%20easy%20encoding%20and%20decoding&url=https://github.com/erikw/nestedtext-ruby&via=erik_westrup&hashtags=nestedtext,ruby,gem)
2
2
  [![Gem Version](https://badge.fury.io/rb/nestedtext.svg)](https://badge.fury.io/rb/nestedtext)
3
3
  [![Gem Downloads](https://ruby-gem-downloads-badge.herokuapp.com/nestedtext?color=brightgreen&type=total&label=gem%20downloads)](https://rubygems.org/gems/nestedtext)
4
4
  [![Data Format Version Supported](https://img.shields.io/badge/%F0%9F%84%BD%F0%9F%85%83%20Version%20Supported-3.2.1-blueviolet)](https://nestedtext.org/en/v3.2/)
5
- [![GitHub Actions: Continuous Integration](https://github.com/erikw/nestedtext-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/erikw/nestedtext-ruby/actions/workflows/ci.yml)
6
5
  [![Official Tests](https://img.shields.io/badge/%F0%9F%8F%81%20Official%20Tests-Passing-success)](https://github.com/KenKundert/nestedtext_tests/tree/585e95a73d94ac1f48e71a154e2db0ab67cf30fa)
6
+ [![GitHub Actions: Continuous Integration](https://github.com/erikw/nestedtext-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/erikw/nestedtext-ruby/actions/workflows/ci.yml)
7
7
  [![GitHub Actions: Continuous Deployment](https://github.com/erikw/nestedtext-ruby/actions/workflows/cd.yml/badge.svg)](https://github.com/erikw/nestedtext-ruby/actions/workflows/cd.yml)
8
8
  [![GitHub Actions: CodeQL Analysis](https://github.com/erikw/nestedtext-ruby/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/erikw/nestedtext-ruby/actions/workflows/codeql-analysis.yml)
9
9
  [![Code Climate Maintainability](https://api.codeclimate.com/v1/badges/8409b6cdc3dc62a33f6f/maintainability)](https://codeclimate.com/github/erikw/nestedtext-ruby/maintainability)
@@ -37,6 +37,25 @@ TODO link to my test repo showin live usage. https://github.com/erikw/nestedtext
37
37
 
38
38
  ## Encoding (writing NT)
39
39
 
40
+ `#to_nt` method:
41
+ ```irb
42
+ irb> require 'nestedtext'
43
+ irb> puts "a\nstring".to_nt
44
+ > a
45
+ > string
46
+ irb> puts ["i1", "i2", "i3"].to_nt
47
+ - i1
48
+ - i2
49
+ - i3
50
+ irb> puts({"k1" => "v1", "multiline\nkey" => "v2", "k3" => "multiline\nvalue"}.to_nt)
51
+ k1: v1
52
+ : multiline
53
+ : key
54
+ > v2
55
+ k3:
56
+ > multiline
57
+ > value
58
+ ```
40
59
  ## Custom Classes Serialization
41
60
  This library has support for serialization/deserialization of custom classes as well.
42
61
  `strict: false` flag needed
@@ -72,9 +91,16 @@ See [encode_custom_classes_test.rb](test/nestedtext/encode_custom_classes_test.r
72
91
  1. Install a supported ruby version (see .gemspec) with a ruby version manager e.g. [rbenv](https://github.com/rbenv/rbenv), [asdf](http://asdf-vm.com/) or [RVM](https://rvm.io/rvm/install)
73
92
  1. run `$ script/setup` to install dependencies
74
93
  1. run `$ script/test` to run the tests
75
- 1. You can also run `$ script/console` for an interactive prompt that will allow you to experiment.
94
+ 1. You can also run `$ script/console` for an interactive prompt that will allow you to experiment.
95
+ 1. For local testing, install the gem on local machine with: `$ bundle exec rake install`.
96
+ * or manuall with `$ gem build *.gemscpec && gem install *.gem`
76
97
 
77
- To install this gem onto your local machine, run `$ bundle exec rake install`.
98
+ Make sure that only intended constants and methods are exposed from the module `NestedText`. Check with
99
+ ```
100
+ irb> require 'nestedtext'
101
+ irb> NestedText.constants
102
+ irb> NestedText.methods(false)
103
+ ```
78
104
 
79
105
  ## Releasing
80
106
  Instructions for releasing on rubygems.org below. Optionally make a GitHub [release](https://github.com/erikw/nestedtext-ruby/releases) after this for the pushed git tag.
@@ -2,4 +2,6 @@ require "stringio"
2
2
  module NestedText
3
3
  TOP_LEVEL_TYPES = [Object, Hash, Array, String]
4
4
  CUSTOM_CLASS_KEY = "__nestedtext_class__"
5
+
6
+ private_constant :TOP_LEVEL_TYPES, :CUSTOM_CLASS_KEY
5
7
  end
@@ -5,12 +5,14 @@ require "nestedtext/encode_helpers"
5
5
  # Or both: add encoding/decoding of more native classes, and allow decoding + applying a schema with 3rd party.
6
6
  # Or encourage using Marshal from core?
7
7
 
8
- class String include NestedText::NTEncodeStrictMixing end
9
- class Array include NestedText::NTEncodeStrictMixing end
10
- class Hash include NestedText::NTEncodeStrictMixing end
8
+ NT_MIXIN = NestedText.const_get(:NTEncodeStrictMixing)
9
+
10
+ class String include NT_MIXIN end
11
+ class Array include NT_MIXIN end
12
+ class Hash include NT_MIXIN end
11
13
 
12
14
  class NilClass
13
- include NestedText::NTEncodeStrictMixing
15
+ include NT_MIXIN
14
16
 
15
17
  def self.nt_create(_data) = nil
16
18
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "nestedtext/parser"
4
4
  require "nestedtext/errors"
5
- require "nestedtext/helpers"
6
5
 
7
6
  require "logger"
8
7
  require "stringio"
@@ -15,16 +14,12 @@ module NestedText
15
14
 
16
15
  raise Errors::WrongInputTypeError.new([String], ntstring) unless ntstring.nil? || ntstring.is_a?(String)
17
16
 
18
- assert_valid_top_level_type top_class
19
-
20
17
  Parser.new(StringIO.new(ntstring), top_class, strict: strict).parse
21
18
  end
22
19
 
23
20
  def self.load_file(filename, top_class: Object, strict: true)
24
21
  raise Errors::WrongInputTypeError.new([String], filename) unless !filename.nil? && filename.is_a?(String)
25
22
 
26
- assert_valid_top_level_type top_class
27
-
28
23
  # Open explicitly in text mode to detect \r as line ending.
29
24
  File.open(filename, mode = "rt") do |file|
30
25
  Parser.new(file, top_class, strict: strict).parse
@@ -174,4 +174,5 @@ module NestedText
174
174
  end
175
175
  end
176
176
  end
177
+ private_constant :Dumper
177
178
  end
@@ -1,11 +1,13 @@
1
1
  require "nestedtext/dumper"
2
2
 
3
+ # TODO: s/Mixing/Mixin/g
3
4
  module NestedText
4
5
  module NTEncodeStrictMixing
5
6
  def to_nt(indentation: 4, strict: true)
6
7
  Dumper.new(EncodeOptions.new(indentation, strict)).dump self
7
8
  end
8
9
  end
10
+ private_constant :NTEncodeStrictMixing
9
11
 
10
12
  module NTEncodeMixing
11
13
  def to_nt(indentation: 4)
@@ -21,4 +23,5 @@ module NestedText
21
23
  @strict = strict
22
24
  end
23
25
  end
26
+ private_constant :EncodeOptions
24
27
  end
@@ -6,12 +6,19 @@ require "word_wrap/core_ext"
6
6
  require "nestedtext/constants"
7
7
 
8
8
  module NestedText
9
- # Top level ParseError for clients to rescue.
10
- class Error < StandardError; end
9
+ # Top level error for clients to rescue on.
10
+ # TODO hide #new so that client's cant create instance of it. Unit test this. https://ruby-doc.org/core-3.1.0/Module.html#private_class_method-method
11
+ class Error < StandardError
12
+ private_class_method :new
13
+ end
11
14
 
12
15
  module Errors
16
+ class InternalError < Error
17
+ public_class_method :new # Prevent clients from instansiating.
18
+ end
19
+
13
20
  # TODO: rename all Subclasses to ParseXError, just like for Dump
14
- class ParseError < Error
21
+ class ParseError < InternalError
15
22
  attr_reader :lineno, :colno, :message_raw
16
23
 
17
24
  def initialize(line, colno, message)
@@ -177,25 +184,7 @@ module NestedText
177
184
  end
178
185
  end
179
186
 
180
- class UnsupportedTopLevelTypeError < Error
181
- def initialize(type_class)
182
- super("The given top level type #{type_class&.name} is unsupported. Chose between #{TOP_LEVEL_TYPES.join(", ")}.")
183
- end
184
- end
185
-
186
- class WrongInputTypeError < Error
187
- def initialize(class_exps, class_act)
188
- super("The given input type #{class_act.class.name} is unsupported. Expected to be of types #{class_exps.map(&:name).join(", ")}")
189
- end
190
- end
191
-
192
- class TopLevelTypeMismatchParsedType < Error
193
- def initialize(class_exp, class_act)
194
- super("The requested top level class #{class_exp.name} is not the same as the actual parsed top level class #{class_act}.")
195
- end
196
- end
197
-
198
- class AssertionError < Error; end
187
+ class AssertionError < InternalError; end
199
188
 
200
189
  class LineScannerIsEmpty < AssertionError
201
190
  def initialize
@@ -209,19 +198,7 @@ module NestedText
209
198
  end
210
199
  end
211
200
 
212
- class DumpBadIO < Error
213
- def initialize(io)
214
- super("When giving the io argument, it must be of type IO (respond to #write, #fsync). Given: #{io.class.name}")
215
- end
216
- end
217
-
218
- class DumpFileBadPath < Error
219
- def initialize(path)
220
- super("Must supply a string to a file path that can be written to. Given: #{path}")
221
- end
222
- end
223
-
224
- class DumpError < Error
201
+ class DumpError < InternalError
225
202
  attr_reader :culprit
226
203
 
227
204
  def initialize(culprit, message)
@@ -258,5 +235,36 @@ module NestedText
258
235
 
259
236
  raise LineTagNotDetected, line
260
237
  end
238
+
239
+ class UnsupportedTopLevelTypeError < InternalError
240
+ def initialize(type_class)
241
+ super("The given top level type #{type_class&.name} is unsupported. Chose between #{TOP_LEVEL_TYPES.join(", ")}.")
242
+ end
243
+ end
244
+
245
+ class WrongInputTypeError < InternalError
246
+ def initialize(class_exps, class_act)
247
+ super("The given input type #{class_act.class.name} is unsupported. Expected to be of types #{class_exps.map(&:name).join(", ")}")
248
+ end
249
+ end
250
+
251
+ class TopLevelTypeMismatchParsedType < InternalError
252
+ def initialize(class_exp, class_act)
253
+ super("The requested top level class #{class_exp.name} is not the same as the actual parsed top level class #{class_act}.")
254
+ end
255
+ end
256
+
257
+ class DumpBadIO < InternalError
258
+ def initialize(io)
259
+ super("When giving the io argument, it must be of type IO (respond to #write, #fsync). Given: #{io.class.name}")
260
+ end
261
+ end
262
+
263
+ class DumpFileBadPath < InternalError
264
+ def initialize(path)
265
+ super("Must supply a string to a file path that can be written to. Given: #{path}")
266
+ end
267
+ end
261
268
  end
269
+ private_constant :Errors
262
270
  end
@@ -4,14 +4,20 @@ require "stringio"
4
4
 
5
5
  require "nestedtext/errors"
6
6
  require "nestedtext/scanners"
7
- require "nestedtext/helpers"
7
+ require "nestedtext/constants"
8
8
 
9
9
  module NestedText
10
10
  class Parser
11
+ def self.assert_valid_top_level_type(top_class)
12
+ unless !top_class.nil? && top_class.is_a?(Class) && TOP_LEVEL_TYPES.map(&:object_id).include?(top_class.object_id)
13
+ raise Errors::UnsupportedTopLevelTypeError, top_class
14
+ end
15
+ end
16
+
11
17
  # TODO: document that caller is responsible for closing IO after done with Parser.
12
18
  def initialize(io, top_class, strict: true)
13
19
  assert_valid_input_type io
14
- NestedText.assert_valid_top_level_type(top_class)
20
+ Parser.assert_valid_top_level_type(top_class)
15
21
  @top_class = top_class
16
22
  @strict = strict
17
23
  @line_scanner = LineScanner.new(io)
@@ -284,4 +290,5 @@ module NestedText
284
290
  result
285
291
  end
286
292
  end
293
+ private_constant :Parser
287
294
  end
@@ -40,6 +40,7 @@ module NestedText
40
40
  @next_line = line
41
41
  end
42
42
  end
43
+ private_constant :LineScanner
43
44
 
44
45
  class InlineScanner
45
46
  attr_reader :line, :pos
@@ -68,6 +69,7 @@ module NestedText
68
69
  empty? ? nil : @line.content[@pos]
69
70
  end
70
71
  end
72
+ private_constant :InlineScanner
71
73
 
72
74
  class Line
73
75
  # Reference: https://nestedtext.org/en/latest/file_format.html
@@ -158,4 +160,5 @@ module NestedText
158
160
  end
159
161
  end
160
162
  end
163
+ private_constant :Line
161
164
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NestedText
4
- VERSION = "0.6.0"
4
+ VERSION = "1.0.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nestedtext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erik Westrup
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-24 00:00:00.000000000 Z
11
+ date: 2022-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: warning
@@ -68,7 +68,6 @@ files:
68
68
  - lib/nestedtext/encode.rb
69
69
  - lib/nestedtext/encode_helpers.rb
70
70
  - lib/nestedtext/errors.rb
71
- - lib/nestedtext/helpers.rb
72
71
  - lib/nestedtext/parser.rb
73
72
  - lib/nestedtext/scanners.rb
74
73
  - lib/nestedtext/version.rb
@@ -1,7 +0,0 @@
1
- module NestedText
2
- def self.assert_valid_top_level_type(top_class)
3
- unless !top_class.nil? && top_class.is_a?(Class) && TOP_LEVEL_TYPES.map(&:object_id).include?(top_class.object_id)
4
- raise Errors::UnsupportedTopLevelTypeError, top_class
5
- end
6
- end
7
- end