nestedtext 4.1.1 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +68 -4
- data/lib/nestedtext/errors_internal.rb +6 -6
- data/lib/nestedtext/version.rb +1 -1
- data/nestedtext.gemspec +18 -16
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e3fcbca130327597aa3a6f2205d5328ddf407a916c5a071906686b5013fca52
|
4
|
+
data.tar.gz: f143d0efe77a919566360830209e8ab36b8a0205feb0466c8c00b55a598da904
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1835a85442d3080bb1084aeed972d787f12325b88f99c50528858596d4918eef73101eb9861fe7a78102a17f9ed27551034a8a237f55143f26d2e74deac3b9e7
|
7
|
+
data.tar.gz: 9998dd2a1d1a1afff99b5cc587a35e6cc240fe38a74c2b19fcb6dd38f3d907c414e1a644a8891832049cfa770eb2a047054e447f48bebbd4481e027eb0ad079f
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [4.2.0] - 2022-02-08
|
10
|
+
### Fixed
|
11
|
+
- Proper Unicode character name lookup.
|
12
|
+
|
9
13
|
## [4.1.1] - 2022-01-28
|
10
14
|
### Fixed
|
11
15
|
- Don't trigger CI when CD will run all tests anyways.
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
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
|
[![Documentation](https://img.shields.io/badge/docs-API-informational?logo=readthedocs&logoColor=violet)](https://www.rubydoc.info/gems/nestedtext/NestedText)
|
5
5
|
[![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/)
|
6
|
-
[![Official Tests](https://img.shields.io/badge/Official%20Tests-Passing-success?logo=cachet)](https://github.com/KenKundert/nestedtext_tests/
|
6
|
+
[![Official Tests](https://img.shields.io/badge/Official%20Tests-Passing-success?logo=cachet)](https://github.com/KenKundert/nestedtext_tests/)
|
7
7
|
[![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)
|
8
8
|
[![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)
|
9
9
|
[![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)
|
@@ -23,6 +23,8 @@ Provided is support for decoding a NestedText file or string to Ruby data struct
|
|
23
23
|
|
24
24
|
This library is inspired Ruby stdlib modules `JSON` and `YAML` as well as the Python [reference implementation](https://github.com/KenKundert/nestedtext) of NestedText. Parsing is done with a LL(1) recursive descent parser and dumping with a recursive DFS traversal of the object references.
|
25
25
|
|
26
|
+
To make this library practically useful, you should pair it with a [schema validator](#schema).
|
27
|
+
|
26
28
|
# What is NestedText?
|
27
29
|
Citing from the official [introduction](https://nestedtext.org/en/latest/index.html) page:
|
28
30
|
> NestedText is a file format for holding structured data to be entered, edited, or viewed by people. It organizes the data into a nested collection of dictionaries, lists, and strings without the need for quoting or escaping. A unique feature of this file format is that it only supports one scalar type: strings. While the decision to eschew integer, real, date, etc. types may seem counter intuitive, it leads to simpler data files and applications that are more robust.
|
@@ -72,14 +74,14 @@ obj1 = NestedText::load(ntstr)
|
|
72
74
|
obj2 = NestedText::load_file("path/to/data.nt")
|
73
75
|
```
|
74
76
|
|
75
|
-
The type of the returned object depends on the top level type in the NestedText data and will be of corresponding native Ruby type. In the example above, `obj1` will be an `Array` and obj2 will be `Hash` if `data.nt` looks like e.g.
|
77
|
+
The type of the returned object depends on the top level type in the NestedText data and will be of corresponding native Ruby type. In the example above, `obj1` will be an `Array` and `obj2` will be `Hash` if `data.nt` looks like e.g.
|
76
78
|
|
77
79
|
```
|
78
80
|
key1: value1
|
79
81
|
key2: value2
|
80
82
|
```
|
81
83
|
|
82
|
-
Thus you must know what you're parsing, or test what you decoded.
|
84
|
+
Thus you must know what you're parsing, or test what you decoded after.
|
83
85
|
|
84
86
|
### Explicit Top Level Type
|
85
87
|
If you already know what you expect to have, you can guarantee that this is what you will get by telling either function what the expected top type is. If not, an error will be raised.
|
@@ -159,7 +161,7 @@ Ruby | NestedText | Comment
|
|
159
161
|
---|---|---
|
160
162
|
`nil` | *Custom Class Encoding* | (1.)
|
161
163
|
`Symbol` | `String` |
|
162
|
-
Custom Class | *Custom Class Encoding* | If the [Custom Class](#custom-classes-serialization) implements `#encode_nt_with`
|
164
|
+
Custom Class | *Custom Class Encoding* | If the [Custom Class](#custom-classes-serialization) implements `#encode_nt_with`
|
163
165
|
Other Class | String | `#to_s` will be called if there is no `#encode_nt_with`
|
164
166
|
|
165
167
|
|
@@ -245,6 +247,68 @@ Apple.new("granny smith", 12).to_nt
|
|
245
247
|
|
246
248
|
See [encode_custom_classes_test.rb](test/nestedtext/encode_custom_classes_test.rb) for more real working examples.
|
247
249
|
|
250
|
+
# Schema
|
251
|
+
The point of NestedText is to not get in to business of supporting ambiguous types. That's why all values are simple strings. Having only simple strings is not useful in practice though. This is why NestedText is intended to be paired with a [Schema Validator](https://nestedtext.org/en/latest/schemas.html)!
|
252
|
+
|
253
|
+
A schema validators can:
|
254
|
+
* assert that the parsed values are like the expected
|
255
|
+
* automatically convert them to Ruby class instances like Integer, Float, etc.
|
256
|
+
|
257
|
+
The reference implementation in Python [lists](https://nestedtext.org/en/latest/examples.html) a few examples of Python validators. Here below is an example of how this Ruby implementation of NestedText can be paired it with [RSchema](https://github.com/tomdalling/rschema).
|
258
|
+
|
259
|
+
## Example with RSchema
|
260
|
+
The full and working example can be found at [erikw/nestedtext-ruby-test](https://github.com/erikw/nestedtext-ruby-test/blob/main/parse_validate.rb).
|
261
|
+
|
262
|
+
Let's say that you have a program that should connect to a few servers. The list of servers should be stored in a configuration file. With NestedText, this file could look like:
|
263
|
+
```yaml
|
264
|
+
-
|
265
|
+
name: global-service
|
266
|
+
ip: 192.167.1.1
|
267
|
+
port: 8080
|
268
|
+
-
|
269
|
+
name: aux-service
|
270
|
+
ip: 17.245.14.2
|
271
|
+
port: 67
|
272
|
+
# Unstable server, don't use this
|
273
|
+
stable: false
|
274
|
+
```
|
275
|
+
|
276
|
+
After parsing this file with this NestedText library, the values for all keys will be string. But for to make practical use of this, we would of course like the values for `port` to be `Integer`, and `stable` should have a value of either `true` or `false`. RSchema can do this conversion for us!
|
277
|
+
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
# Define schema for our list of servers
|
281
|
+
schema = RSchema.define do
|
282
|
+
array(
|
283
|
+
hash(
|
284
|
+
'name' => _String,
|
285
|
+
'ip' => _String,
|
286
|
+
'port' => _Integer,
|
287
|
+
optional('stable') => boolean
|
288
|
+
)
|
289
|
+
)
|
290
|
+
end
|
291
|
+
|
292
|
+
# The coercer will automatially convert types
|
293
|
+
coercer = RSchema::CoercionWrapper::RACK_PARAMS.wrap(schema)
|
294
|
+
|
295
|
+
# Parse config file with NestedText
|
296
|
+
data = NestedText.load_file('conf.nt')
|
297
|
+
|
298
|
+
# Validate
|
299
|
+
result = coercer.validate(data_success)
|
300
|
+
|
301
|
+
if result.valid?
|
302
|
+
servers = result.value
|
303
|
+
# Now 'servers' is known to be valid and have the types specified in the schema.
|
304
|
+
# Thus, we can use it now!
|
305
|
+
stable_servers = servers.select { |server| server['stable'] }
|
306
|
+
# Not a meaningful sum - just demonstrating that 'port's are integers and not strings anymore!
|
307
|
+
port_sum = servers.map { |server| server['port'] }.sum
|
308
|
+
else
|
309
|
+
puts result.error
|
310
|
+
end
|
311
|
+
```
|
248
312
|
|
249
313
|
# Installation
|
250
314
|
1. Add this gem to your ruby project's Gemfile
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'word_wrap'
|
4
4
|
require 'word_wrap/core_ext'
|
5
|
+
require 'unicode_utils'
|
5
6
|
|
6
7
|
require 'nestedtext/constants'
|
7
8
|
require 'nestedtext/error'
|
@@ -162,14 +163,13 @@ module NestedText
|
|
162
163
|
|
163
164
|
class ParseInvalidIndentationCharError < ParseError
|
164
165
|
def initialize(line)
|
165
|
-
|
166
|
+
char = line.content[0]
|
167
|
+
# Official-test kludge; Translate rubys \u00 to python's unicodedata.name \x format.
|
168
|
+
printable_char = char.dump.gsub(/"/, '').gsub(/\\u0*/, '\x').downcase
|
166
169
|
|
167
|
-
# Looking for non-breaking space is just to be compatible with official tests.
|
168
170
|
explanation = ''
|
169
|
-
|
170
|
-
|
171
|
-
explanation = ' (NO-BREAK SPACE)'
|
172
|
-
end
|
171
|
+
# Official-test kludge; ASCII chars have printable names too, but they are not used in reference implementation.
|
172
|
+
explanation = " (#{UnicodeUtils.char_name(char)})" unless char.ord < 128
|
173
173
|
|
174
174
|
message = "invalid character in indentation: '#{printable_char}'#{explanation}."
|
175
175
|
super(line, line.indentation, message)
|
data/lib/nestedtext/version.rb
CHANGED
data/nestedtext.gemspec
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'lib/nestedtext/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
6
|
+
spec.name = 'nestedtext'
|
7
7
|
spec.version = NestedText::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.authors = ['Erik Westrup']
|
9
|
+
spec.email = ['erik.westrup@gmail.com']
|
10
10
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
15
|
-
spec.required_ruby_version = [
|
11
|
+
spec.summary = 'A ruby library for the human friendly data format NestedText (https://nestedtext.org/)'
|
12
|
+
spec.description = 'A ruby library for the human friendly data format NestedText (https://nestedtext.org/). There is support for decoding a NestedText file or string to Ruby data structures, as well as encoding Ruby objects to a NestedText file or string. Furthermore there is support for serialization and deserialization of custom classes. Support for v3.2.1 of the data format will all official tests passing.'
|
13
|
+
spec.homepage = 'https://github.com/erikw/nestedtext-ruby/'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
spec.required_ruby_version = ['>= 3.0', '< 4']
|
16
16
|
|
17
|
-
spec.metadata[
|
18
|
-
spec.metadata[
|
19
|
-
spec.metadata[
|
17
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
18
|
+
spec.metadata['source_code_uri'] = 'https://github.com/erikw/nestedtext-ruby/'
|
19
|
+
spec.metadata['changelog_uri'] = 'https://github.com/erikw/nestedtext-ruby/blob/main/CHANGELOG.md'
|
20
20
|
|
21
21
|
# For push to GitHub packages to work.
|
22
22
|
# Reference: https://github.community/t/unable-to-push-rubygem-to-package-registry-the-expected-resource-was-not-found/14596/7
|
23
23
|
spec.metadata = {
|
24
|
-
|
24
|
+
'github_repo' => 'git@github.com:erikw/nestedtext-ruby.git',
|
25
|
+
'rubygems_mfa_required' => 'true'
|
25
26
|
}
|
26
27
|
|
27
28
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
@@ -29,8 +30,9 @@ Gem::Specification.new do |spec|
|
|
29
30
|
f.match(%r{\A(?:lib/|CHANGELOG.md|CONTRIBUTING.md|LICENSE.txt|README.md|SECURITY.md|nestedtext.gemspec)})
|
30
31
|
end
|
31
32
|
end
|
32
|
-
spec.require_paths = [
|
33
|
+
spec.require_paths = ['lib']
|
33
34
|
|
34
|
-
spec.add_runtime_dependency
|
35
|
-
spec.add_runtime_dependency
|
35
|
+
spec.add_runtime_dependency 'unicode_utils', '~> 1.4'
|
36
|
+
spec.add_runtime_dependency 'warning', '~> 1.2'
|
37
|
+
spec.add_runtime_dependency 'word_wrap', '~> 1.0'
|
36
38
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nestedtext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.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-
|
11
|
+
date: 2022-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: unicode_utils
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: warning
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +88,7 @@ licenses:
|
|
74
88
|
- MIT
|
75
89
|
metadata:
|
76
90
|
github_repo: git@github.com:erikw/nestedtext-ruby.git
|
91
|
+
rubygems_mfa_required: 'true'
|
77
92
|
post_install_message:
|
78
93
|
rdoc_options: []
|
79
94
|
require_paths:
|