tinycode 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/.rspec +2 -0
- data/.rubocop.yml +51 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +81 -0
- data/LICENSE +674 -0
- data/README.md +159 -0
- data/Rakefile +19 -0
- data/lib/tinycode/core_ext.rb +54 -0
- data/lib/tinycode/fixed_integer.rb +66 -0
- data/lib/tinycode/module.rb +164 -0
- data/lib/tinycode/no_core_ext.rb +3 -0
- data/lib/tinycode/version.rb +5 -0
- data/lib/tinycode.rb +4 -0
- data/tinycode.gemspec +42 -0
- metadata +173 -0
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# Tinycode
|
2
|
+
|
3
|
+
This gem provides an encoder and decoder for tinycode, which is a bencode like
|
4
|
+
encoding that supports more data-types and slightly smaller encoded sizes.
|
5
|
+
|
6
|
+
The encoder supports arrays, hashes, strings, symbols, and integers, as well as
|
7
|
+
specialized fixed-width integers: `Tinycode::U8`, `Tinycode::U16`,
|
8
|
+
`Tinycode::U32`, and `Tinycode::U64`.
|
9
|
+
Like [YAML] but unlike [JSON], this encoder maintains a distinction between
|
10
|
+
strings and symbols.
|
11
|
+
|
12
|
+
The encoding is inspired by [BEncode]'s tag-length-value construction for strings, which eliminates the need for escaping in Strings.
|
13
|
+
This makes this encoding particularly appropriate for serializing binary strings
|
14
|
+
directly.
|
15
|
+
|
16
|
+
[YAML]: https://ruby-doc.org/stdlib-3.0.2/libdoc/yaml/rdoc/YAML.html
|
17
|
+
[JSON]: https://ruby-doc.org/stdlib-3.0.2/libdoc/json/rdoc/JSON.html
|
18
|
+
[BEncode]: https://en.wikipedia.org/wiki/Bencode
|
19
|
+
|
20
|
+
## Demo
|
21
|
+
|
22
|
+
Consider the following data structure:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
[
|
26
|
+
{
|
27
|
+
location: 'Chicago',
|
28
|
+
currently: {
|
29
|
+
temperature: 72,
|
30
|
+
condition: ['Partly cloudy', 'Chance of rain']
|
31
|
+
},
|
32
|
+
narrative: "High: 81, low: 56\nCooler than yesterday.",
|
33
|
+
high: 81,
|
34
|
+
low: 56
|
35
|
+
},
|
36
|
+
{
|
37
|
+
location: 'New York',
|
38
|
+
currently: {
|
39
|
+
temperature: 45,
|
40
|
+
condition: ['Rainy']
|
41
|
+
},
|
42
|
+
narrative: "High: 56, low: -2\nWinter Weather Alert in effect.",
|
43
|
+
high: 56,
|
44
|
+
low: -2
|
45
|
+
}
|
46
|
+
]
|
47
|
+
```
|
48
|
+
|
49
|
+
The resulting structure looks something like this. In actuality, there is not
|
50
|
+
this much whitespace, and the \xNN codes represent binary values.
|
51
|
+
|
52
|
+
```plain
|
53
|
+
[
|
54
|
+
{
|
55
|
+
currently:{
|
56
|
+
condition:[
|
57
|
+
Partly cloudy'
|
58
|
+
Chance of rain'
|
59
|
+
]
|
60
|
+
temperature:+\x48
|
61
|
+
}
|
62
|
+
high:+\x51
|
63
|
+
location:Chicago'
|
64
|
+
low:+\x38
|
65
|
+
narrative:'\x28High: 81, low: 56\nCooler than yesterday.
|
66
|
+
}
|
67
|
+
{
|
68
|
+
currently:{condition:[Rainy']temperature:+\x2D}
|
69
|
+
high:+\x38
|
70
|
+
location:New York'
|
71
|
+
low:-\x02
|
72
|
+
narrative:'\x31High: 56, low: -2\nWinter Weather Alert in effect.
|
73
|
+
}
|
74
|
+
]
|
75
|
+
```
|
76
|
+
|
77
|
+
## Installation
|
78
|
+
|
79
|
+
Add this line to your application's Gemfile:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
gem 'tinycode'
|
83
|
+
```
|
84
|
+
|
85
|
+
And then execute:
|
86
|
+
|
87
|
+
```sh
|
88
|
+
$ bundle install
|
89
|
+
```
|
90
|
+
|
91
|
+
Or install it yourself as:
|
92
|
+
|
93
|
+
```sh
|
94
|
+
$ gem install tinycode
|
95
|
+
```
|
96
|
+
|
97
|
+
## Usage
|
98
|
+
|
99
|
+
### Dumping a data structure
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
require 'tinycode'
|
103
|
+
|
104
|
+
42.tinycode
|
105
|
+
['some', 'array'].tinycode
|
106
|
+
# and so on
|
107
|
+
```
|
108
|
+
|
109
|
+
Alternatively you can use `Tinycode.dump`:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
# can use 'tinycode/no_core_ext' instead if class extensions are unwanted
|
113
|
+
require 'tinycode'
|
114
|
+
|
115
|
+
Tinycode.dump(42)
|
116
|
+
Tinycode.dump(['some', 'array'])
|
117
|
+
# and so on
|
118
|
+
```
|
119
|
+
|
120
|
+
### Restoring a data structure
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
require 'tinycode'
|
124
|
+
|
125
|
+
Tinycode.load("+\x2A".b) # => 42
|
126
|
+
Tinycode.load("[some'array']".b) # => ['some', 'array']
|
127
|
+
# and so on
|
128
|
+
```
|
129
|
+
|
130
|
+
## Development
|
131
|
+
|
132
|
+
After checking out the repo, run `bundle install` to install dependencies. Then,
|
133
|
+
run `rake watch` to run yard, tests, and linting on every file save.
|
134
|
+
|
135
|
+
To install this gem onto your local machine, run `rake install`.
|
136
|
+
|
137
|
+
To release a new version, update the version number in `version.rb`.
|
138
|
+
Then run `rake release`, which will create/push a git tag for the version and
|
139
|
+
publish the `.gem` file to [rubygems.org].
|
140
|
+
|
141
|
+
[rubygems.org]: https://rubygems.org
|
142
|
+
|
143
|
+
## License
|
144
|
+
|
145
|
+
All copyright rights are held by the authors as recorded in git.
|
146
|
+
See the commit history for a comprehensive listing of copyright holders and
|
147
|
+
copyright dates.
|
148
|
+
|
149
|
+
This program is free software: you can redistribute it and/or modify
|
150
|
+
it under the terms of the GNU General Public License as published by
|
151
|
+
the Free Software Foundation, either version 3 of the License, or
|
152
|
+
(at your option) any later version.
|
153
|
+
|
154
|
+
This program is distributed in the hope that it will be useful,
|
155
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
156
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
157
|
+
GNU General Public License for more details.
|
158
|
+
|
159
|
+
See LICENSE in this repository for the full license text.
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
require 'yard'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new(:spec)
|
10
|
+
RuboCop::RakeTask.new(:lint) do |task|
|
11
|
+
task.options = %w[--except Metrics]
|
12
|
+
end
|
13
|
+
YARD::Rake::YardocTask.new
|
14
|
+
|
15
|
+
task :watch do
|
16
|
+
sh 'rerun -p "{**/*.{rb,gemspec},exe/**/*,Gemfile*,Rakefile}" -x rake yard spec lint:auto_correct'
|
17
|
+
end
|
18
|
+
|
19
|
+
task default: [:yard, :spec, :lint]
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Style/Documentation
|
4
|
+
|
5
|
+
|
6
|
+
class Array
|
7
|
+
def tinycode
|
8
|
+
Tinycode.dump(self)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Hash
|
13
|
+
def tinycode
|
14
|
+
Tinycode.dump(self)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class String
|
19
|
+
def tinycode
|
20
|
+
Tinycode.dump(self)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Symbol
|
25
|
+
def tinycode
|
26
|
+
Tinycode.dump(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Integer
|
31
|
+
def tinycode
|
32
|
+
Tinycode.dump(self)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class TrueClass
|
37
|
+
def tinycode
|
38
|
+
Tinycode.dump(self)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class FalseClass
|
43
|
+
def tinycode
|
44
|
+
Tinycode.dump(self)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class NilClass
|
49
|
+
def tinycode
|
50
|
+
Tinycode.dump(self)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# rubocop:enable Style/Documentation
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tinycode
|
4
|
+
# Mixin module for U8, U16, U32, and U64 classes
|
5
|
+
module FixedInteger
|
6
|
+
attr_reader :value
|
7
|
+
alias to_i value
|
8
|
+
alias to_int value
|
9
|
+
|
10
|
+
def initialize(value)
|
11
|
+
raise ArgumentError, "#{value.class} cannot be converted to integer" unless value.respond_to?(:to_int)
|
12
|
+
|
13
|
+
@value = value.to_int
|
14
|
+
|
15
|
+
raise RangeError, "#{@value.inspect} out of range for #{self.class}" unless self.class.range.include?(@value)
|
16
|
+
end
|
17
|
+
|
18
|
+
def tinycode
|
19
|
+
Tinycode.dump(self)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
value.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def inspect
|
27
|
+
"#<#{self.class} value=#{value.inspect}>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def ==(other)
|
31
|
+
value == other.value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# an unsigned integer that takes up exactly 8 bits
|
36
|
+
class U8
|
37
|
+
include FixedInteger
|
38
|
+
def self.range
|
39
|
+
0x00..0xFF
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# an unsigned integer that takes up exactly 16 bits
|
44
|
+
class U16
|
45
|
+
include FixedInteger
|
46
|
+
def self.range
|
47
|
+
0x0000..0xFFFF
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# an unsigned integer that takes up exactly 32 bits
|
52
|
+
class U32
|
53
|
+
include FixedInteger
|
54
|
+
def self.range
|
55
|
+
0x00000000..0xFFFFFFFF
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# an unsigned integer that takes up exactly 64 bits
|
60
|
+
class U64
|
61
|
+
include FixedInteger
|
62
|
+
def self.range
|
63
|
+
0x00000000_00000000..0xFFFFFFFF_FFFFFFFF
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'fixed_integer'
|
4
|
+
require_relative 'version'
|
5
|
+
|
6
|
+
# An encoder and decoder for tinycode, which is a bencode like encoding that
|
7
|
+
# supports more data-types and slightly smaller encoded sizes.
|
8
|
+
module Tinycode
|
9
|
+
class ParseError < StandardError; end
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def dump(obj)
|
13
|
+
case obj
|
14
|
+
when Array then dump_array(obj)
|
15
|
+
when Hash then dump_hash(obj)
|
16
|
+
when String then dump_string(obj)
|
17
|
+
when Symbol then dump_symbol(obj)
|
18
|
+
when Integer then dump_integer(obj)
|
19
|
+
when U8 then dump_fixed_integer(obj, code: '%', pack: 'aC')
|
20
|
+
when U16 then dump_fixed_integer(obj, code: '$', pack: 'aS>')
|
21
|
+
when U32 then dump_fixed_integer(obj, code: '!', pack: 'aL>')
|
22
|
+
when U64 then dump_fixed_integer(obj, code: '#', pack: 'aQ>')
|
23
|
+
when nil then "\0".b
|
24
|
+
when true then '?T'.b
|
25
|
+
when false then '?F'.b
|
26
|
+
else raise ArgumentError, "Don't know how to dump #{obj.class}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def load(tinycode)
|
31
|
+
raise ArgumentError, "Cannot convert #{Tinycode.class} to String" if !tinycode.respond_to?(:to_str)
|
32
|
+
|
33
|
+
tinycode = tinycode.to_str.b
|
34
|
+
struct, length = load_with_length(tinycode)
|
35
|
+
raise ParseError, 'Input is longer than expected' if length != tinycode.length
|
36
|
+
|
37
|
+
struct
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def load_with_length(tinycode)
|
43
|
+
case tinycode[0]
|
44
|
+
when /[\w \t\n]/ then load_id(tinycode)
|
45
|
+
when '[' then load_array(tinycode)
|
46
|
+
when '{' then load_hash(tinycode)
|
47
|
+
when "'" then load_string(tinycode)
|
48
|
+
when ':' then load_symbol(tinycode)
|
49
|
+
when '-', '+' then load_integer(tinycode)
|
50
|
+
when '%' then load_fixed_integer(tinycode, U8, length: 1, unpack: 'C')
|
51
|
+
when '$' then load_fixed_integer(tinycode, U16, length: 2, unpack: 'S>')
|
52
|
+
when '!' then load_fixed_integer(tinycode, U32, length: 4, unpack: 'L>')
|
53
|
+
when '#' then load_fixed_integer(tinycode, U64, length: 8, unpack: 'Q>')
|
54
|
+
when "\0" then [nil, 1]
|
55
|
+
when '?' then load_boolean(tinycode)
|
56
|
+
else raise ParseError, "Unexpected character: #{tinycode[0]}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def dump_array(ary)
|
61
|
+
"[#{ary.map(&method(:dump)).join}]".b
|
62
|
+
end
|
63
|
+
|
64
|
+
def load_array(tinycode)
|
65
|
+
offset = 1
|
66
|
+
result = []
|
67
|
+
until tinycode[offset] == ']'
|
68
|
+
value, length = load_with_length(tinycode[offset..])
|
69
|
+
result << value
|
70
|
+
offset += length
|
71
|
+
end
|
72
|
+
[result, offset + 1]
|
73
|
+
end
|
74
|
+
|
75
|
+
def dump_hash(hash)
|
76
|
+
"{#{hash.sort.flatten(1).map(&method(:dump)).join}}".b
|
77
|
+
end
|
78
|
+
|
79
|
+
def load_hash(tinycode)
|
80
|
+
offset = 1
|
81
|
+
result = {}
|
82
|
+
until tinycode[offset] == '}'
|
83
|
+
key, key_length = load_with_length(tinycode[offset..])
|
84
|
+
offset += key_length
|
85
|
+
value, value_length = load_with_length(tinycode[offset..])
|
86
|
+
offset += value_length
|
87
|
+
raise if result.key?(key)
|
88
|
+
|
89
|
+
result[key] = value
|
90
|
+
end
|
91
|
+
[result, offset + 1]
|
92
|
+
end
|
93
|
+
|
94
|
+
def dump_string(str, code: "'")
|
95
|
+
str = str.encode('UTF-8').b unless str.encoding == Encoding::ASCII_8BIT
|
96
|
+
if str =~ /\A[\w \t\n]+\z/
|
97
|
+
[str, code].pack('a*a')
|
98
|
+
else
|
99
|
+
[code, str.length, str].pack('awa*')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def load_id(tinycode)
|
104
|
+
length = tinycode.index(/[':]/)
|
105
|
+
value = tinycode[...length]
|
106
|
+
value = if tinycode[length] == ':'
|
107
|
+
value.to_sym
|
108
|
+
else
|
109
|
+
value.force_encoding('UTF-8')
|
110
|
+
end
|
111
|
+
[value, length + 1]
|
112
|
+
end
|
113
|
+
|
114
|
+
def load_string(tinycode)
|
115
|
+
str_length, offset = load_varint(tinycode[1..])
|
116
|
+
[tinycode[(1 + offset)...(1 + offset + str_length)].force_encoding('UTF-8'), 1 + offset + str_length]
|
117
|
+
end
|
118
|
+
|
119
|
+
def dump_symbol(sym)
|
120
|
+
dump_string(sym.name, code: ':')
|
121
|
+
end
|
122
|
+
|
123
|
+
def load_symbol(sym)
|
124
|
+
value, offset = load_string(sym)
|
125
|
+
[value.to_sym, offset]
|
126
|
+
end
|
127
|
+
|
128
|
+
def dump_integer(num)
|
129
|
+
if num < 0
|
130
|
+
['-', -num].pack('aw')
|
131
|
+
else
|
132
|
+
['+', num].pack('aw')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def load_integer(tinycode)
|
137
|
+
value, offset = load_varint(tinycode[1..])
|
138
|
+
value = -value if tinycode[0] == '-'
|
139
|
+
|
140
|
+
[value, 1 + offset]
|
141
|
+
end
|
142
|
+
|
143
|
+
def dump_fixed_integer(num, code:, pack:)
|
144
|
+
[code, num].pack(pack)
|
145
|
+
end
|
146
|
+
|
147
|
+
def load_fixed_integer(tinycode, clazz, length:, unpack:)
|
148
|
+
[clazz.new(tinycode[1...(1 + length)].unpack1(unpack)), 1 + length]
|
149
|
+
end
|
150
|
+
|
151
|
+
def load_varint(tinycode)
|
152
|
+
length = tinycode.each_byte.lazy.take_while {|b| b > 0x7F }.count + 1
|
153
|
+
[tinycode[...length].unpack1('w'), length]
|
154
|
+
end
|
155
|
+
|
156
|
+
def load_boolean(tinycode)
|
157
|
+
case tinycode[1]
|
158
|
+
when 'T' then [true, 2]
|
159
|
+
when 'F' then [false, 2]
|
160
|
+
else raise ParseError, 'Malformed boolean'
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
data/lib/tinycode.rb
ADDED
data/tinycode.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/tinycode/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'tinycode'
|
7
|
+
spec.version = Tinycode::VERSION
|
8
|
+
spec.summary = 'An encoder and decoder for tinycode'
|
9
|
+
spec.description = 'tinycode is a bencode like encoding that supports more ' \
|
10
|
+
'data-types and slightly smaller encoded sizes.'
|
11
|
+
spec.authors = ['Alex Gittemeier']
|
12
|
+
spec.license = 'GPL-3.0'
|
13
|
+
spec.email = ['me@a.lexg.dev']
|
14
|
+
spec.metadata['source_code_uri'] = 'https://gitlab.com/windows93/tinycode'
|
15
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
16
|
+
# spec.metadata['changelog_uri'] =
|
17
|
+
|
18
|
+
spec.homepage = spec.metadata['source_code_uri']
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
20
|
+
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
spec.bindir = 'exe'
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) {|f| File.basename(f) }
|
30
|
+
spec.require_paths = ['lib']
|
31
|
+
|
32
|
+
spec.required_ruby_version = '>= 3.0.0'
|
33
|
+
|
34
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
35
|
+
spec.add_development_dependency 'rerun', '~> 0.13'
|
36
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
37
|
+
spec.add_development_dependency 'rubocop', '~> 1.21'
|
38
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.6'
|
39
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 2.6'
|
40
|
+
spec.add_development_dependency 'simplecov', '~> 0.21'
|
41
|
+
spec.add_development_dependency 'yard', '~> 0.9'
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tinycode
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Gittemeier
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-11-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '13.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '13.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rerun
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.13'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.13'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.21'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.21'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.21'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.21'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: yard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.9'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.9'
|
125
|
+
description: tinycode is a bencode like encoding that supports more data-types and
|
126
|
+
slightly smaller encoded sizes.
|
127
|
+
email:
|
128
|
+
- me@a.lexg.dev
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".rspec"
|
134
|
+
- ".rubocop.yml"
|
135
|
+
- Gemfile
|
136
|
+
- Gemfile.lock
|
137
|
+
- LICENSE
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- lib/tinycode.rb
|
141
|
+
- lib/tinycode/core_ext.rb
|
142
|
+
- lib/tinycode/fixed_integer.rb
|
143
|
+
- lib/tinycode/module.rb
|
144
|
+
- lib/tinycode/no_core_ext.rb
|
145
|
+
- lib/tinycode/version.rb
|
146
|
+
- tinycode.gemspec
|
147
|
+
homepage: https://gitlab.com/windows93/tinycode
|
148
|
+
licenses:
|
149
|
+
- GPL-3.0
|
150
|
+
metadata:
|
151
|
+
source_code_uri: https://gitlab.com/windows93/tinycode
|
152
|
+
rubygems_mfa_required: 'true'
|
153
|
+
homepage_uri: https://gitlab.com/windows93/tinycode
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - ">="
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: 3.0.0
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubygems_version: 3.2.22
|
170
|
+
signing_key:
|
171
|
+
specification_version: 4
|
172
|
+
summary: An encoder and decoder for tinycode
|
173
|
+
test_files: []
|