teptris 0.1.0-aarch64-linux
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/lib/libteptris.so +0 -0
- data/lib/teptris/error.rb +13 -0
- data/lib/teptris/lib.rb +81 -0
- data/lib/teptris/toml.rb +313 -0
- data/lib/teptris/version.rb +3 -0
- data/lib/teptris.rb +10 -0
- metadata +63 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: bc7b7a460eed58ef49cf570c98a17a7f486455633791c414dde64c8215bb9e41
|
|
4
|
+
data.tar.gz: 36af2426f341a01ba13d94a516fdccb0b15c72f634aac0558faf7e07d483f08f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8284c3d7121fd91e85fe610797b97fc3ba44f71ad2c83343c64e5e31de5a33ab0b3121188f0d32221b4fd73348b2968fc0c33abe2351ac44821cd1cf0fffe511
|
|
7
|
+
data.tar.gz: 98f11f1b07407a8390d6b18770359175e8c3b4d7b8e3f09d04efb3c2f36db7c3163116fd5fb8455c9416ce93872023d216754aa636abb81028624bae90aec9c4
|
data/lib/libteptris.so
ADDED
|
Binary file
|
data/lib/teptris/lib.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require "ffi"
|
|
2
|
+
|
|
3
|
+
module Teptris
|
|
4
|
+
# Loads the shared libteptris: TEPTRIS_LIB_PATH env, vendored
|
|
5
|
+
# lib/platform/<tag>/, the sibling C checkout's build tree, then the
|
|
6
|
+
# system paths (yeptris-ruby resolution chain).
|
|
7
|
+
module Lib
|
|
8
|
+
extend FFI::Library
|
|
9
|
+
|
|
10
|
+
NAMES = %w[libteptris.dylib libteptris.so libteptris.dll].freeze
|
|
11
|
+
|
|
12
|
+
def self.candidates
|
|
13
|
+
out = []
|
|
14
|
+
out << ENV["TEPTRIS_LIB_PATH"] if ENV["TEPTRIS_LIB_PATH"]
|
|
15
|
+
out.concat(Dir[File.expand_path("../libteptris.*", __dir__)])
|
|
16
|
+
NAMES.each do |n|
|
|
17
|
+
%w[build build-release build-shared build-bench].each do |b|
|
|
18
|
+
out << File.expand_path("../../teptris/#{b}/src/#{n}", __dir__)
|
|
19
|
+
end
|
|
20
|
+
out << n
|
|
21
|
+
end
|
|
22
|
+
out.compact
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
loaded = nil
|
|
26
|
+
candidates.each do |c|
|
|
27
|
+
begin
|
|
28
|
+
ffi_lib c
|
|
29
|
+
loaded = c
|
|
30
|
+
break
|
|
31
|
+
rescue LoadError
|
|
32
|
+
next
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
raise Error, "libteptris not found (set TEPTRIS_LIB_PATH)" unless loaded
|
|
36
|
+
LIBRARY_PATH = loaded
|
|
37
|
+
|
|
38
|
+
typedef :pointer, :doc
|
|
39
|
+
typedef :pointer, :node
|
|
40
|
+
|
|
41
|
+
attach_function :teptris_parse, [:pointer, :size_t, :pointer, :pointer], :int
|
|
42
|
+
attach_function :teptris_document_free, [:doc], :void
|
|
43
|
+
attach_function :teptris_document_error, [:doc], :pointer
|
|
44
|
+
attach_function :teptris_document_root, [:doc], :node
|
|
45
|
+
attach_function :teptris_document_emit, [:doc, :pointer, :pointer], :int
|
|
46
|
+
attach_function :teptris_node_kind, [:node], :int
|
|
47
|
+
attach_function :teptris_node_string, [:node, :pointer], :int
|
|
48
|
+
attach_function :teptris_node_integer, [:node, :pointer], :int
|
|
49
|
+
attach_function :teptris_node_float, [:node, :pointer], :int
|
|
50
|
+
attach_function :teptris_node_boolean, [:node, :pointer], :int
|
|
51
|
+
attach_function :teptris_node_datetime, [:node, :pointer], :int
|
|
52
|
+
attach_function :teptris_node_array_length, [:node], :size_t
|
|
53
|
+
attach_function :teptris_node_array_at, [:node, :size_t], :node
|
|
54
|
+
attach_function :teptris_node_table_length, [:node], :size_t
|
|
55
|
+
attach_function :teptris_node_table_at, [:node, :size_t, :pointer], :node
|
|
56
|
+
attach_function :teptris_document_flatten, [:doc, :pointer, :pointer], :int
|
|
57
|
+
attach_function :teptris_flatten_free, [:pointer], :void
|
|
58
|
+
|
|
59
|
+
class ErrorStruct < FFI::Struct
|
|
60
|
+
layout :status, :int, :line, :size_t, :column, :size_t, :message, :string
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class ViewStruct < FFI::Struct
|
|
64
|
+
layout :ptr, :pointer, :len, :size_t
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
class DateTimeStruct < FFI::Struct
|
|
68
|
+
layout :year, :int32,
|
|
69
|
+
:month, :uint8, :day, :uint8,
|
|
70
|
+
:hour, :uint8, :minute, :uint8, :second, :uint8,
|
|
71
|
+
:_pad, [:uint8, 3],
|
|
72
|
+
:nanosecond, :uint32, :offset_seconds, :int32
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
KIND = {
|
|
77
|
+
string: 0, integer: 1, float: 2, boolean: 3,
|
|
78
|
+
datetime: 4, datetime_local: 5, date_local: 6, time_local: 7,
|
|
79
|
+
array: 8, table: 9
|
|
80
|
+
}.freeze
|
|
81
|
+
end
|
data/lib/teptris/toml.rb
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
require "date"
|
|
2
|
+
|
|
3
|
+
require_relative "error"
|
|
4
|
+
require_relative "lib"
|
|
5
|
+
require_relative "version"
|
|
6
|
+
|
|
7
|
+
module Teptris
|
|
8
|
+
# API shape mirrors the tomlib gem: load/dump, String keys, and the
|
|
9
|
+
# tomlib datetime contract (Time with zone for offset datetimes, local
|
|
10
|
+
# Time for local datetimes, Date for dates, String "HH:MM:SS" for
|
|
11
|
+
# local times).
|
|
12
|
+
module TOML
|
|
13
|
+
class << self
|
|
14
|
+
def load(toml)
|
|
15
|
+
parse_and_materialize(toml, 0, nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Safe-load shaped entry point for frameworks: permitted_classes
|
|
19
|
+
# restricts datetime materialization (raise when a value would
|
|
20
|
+
# materialize an unpermitted class); datetime_policy :string keeps
|
|
21
|
+
# every datetime kind as its canonical ISO string instead.
|
|
22
|
+
def safe_load(toml, permitted_classes: nil, datetime_policy: :native)
|
|
23
|
+
unless %i[native string].include?(datetime_policy)
|
|
24
|
+
raise ArgumentError, "datetime_policy must be :native or :string"
|
|
25
|
+
end
|
|
26
|
+
mode = datetime_policy == :string ? 1 : 0
|
|
27
|
+
permitted = permitted_classes && Set.new(permitted_classes)
|
|
28
|
+
if permitted && mode.zero?
|
|
29
|
+
permitted << String # TOML scalars are always materialized
|
|
30
|
+
end
|
|
31
|
+
parse_and_materialize(toml, mode, permitted)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Reserved: fused descriptor materialization, the same descriptor
|
|
35
|
+
# shape as leptris/yeptris#238 — see docs/DESCRIPTOR_ABI.md. The
|
|
36
|
+
# entry point exists so frameworks can code against it today; the
|
|
37
|
+
# fused native pass lands with the co-designed ABI.
|
|
38
|
+
def load_schema(toml, descriptor)
|
|
39
|
+
raise Error,
|
|
40
|
+
"descriptor materialization lands with the co-designed " \
|
|
41
|
+
"ABI (leptris/yeptris#238); entry point is reserved — " \
|
|
42
|
+
"see docs/DESCRIPTOR_ABI.md (descriptor #{descriptor.class})"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def parse_and_materialize(toml, mode, permitted)
|
|
48
|
+
raise ArgumentError, "input must be a String" unless toml.is_a?(String)
|
|
49
|
+
|
|
50
|
+
data = FFI::MemoryPointer.from_string(toml)
|
|
51
|
+
docp = FFI::MemoryPointer.new(:pointer)
|
|
52
|
+
st = Lib.teptris_parse(data, toml.bytesize, nil, docp)
|
|
53
|
+
handle = docp.read_pointer
|
|
54
|
+
if st != Teptris::TEPTRIS_OK
|
|
55
|
+
raise build_parse_error(handle)
|
|
56
|
+
end
|
|
57
|
+
begin
|
|
58
|
+
@mode = mode
|
|
59
|
+
@permitted = permitted
|
|
60
|
+
load_flat(handle)
|
|
61
|
+
ensure
|
|
62
|
+
@mode = nil
|
|
63
|
+
@permitted = nil
|
|
64
|
+
Lib.teptris_document_free(handle)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
public
|
|
69
|
+
|
|
70
|
+
def load_file(path)
|
|
71
|
+
load(File.read(path))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def dump(obj)
|
|
75
|
+
raise ArgumentError, "cannot dump #{obj.class}" unless obj.is_a?(Hash)
|
|
76
|
+
|
|
77
|
+
out = +""
|
|
78
|
+
emit_table(obj, out, nil)
|
|
79
|
+
out
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
private
|
|
83
|
+
|
|
84
|
+
def build_parse_error(handle)
|
|
85
|
+
line = 0
|
|
86
|
+
column = 0
|
|
87
|
+
msg = "parse failed"
|
|
88
|
+
unless handle.null?
|
|
89
|
+
es = Lib::ErrorStruct.new(Lib.teptris_document_error(handle))
|
|
90
|
+
line = es[:line]
|
|
91
|
+
column = es[:column]
|
|
92
|
+
msg = es[:message]
|
|
93
|
+
end
|
|
94
|
+
ParseError.new(msg, line, column)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# One-bulk-drain load: the C side flattens the whole tree in a
|
|
98
|
+
# single crossing; this decoder walks the typed flat buffer.
|
|
99
|
+
FLAT_TABLE = 0x01
|
|
100
|
+
FLAT_ARRAY = 0x02
|
|
101
|
+
FLAT_STRING = 0x03
|
|
102
|
+
FLAT_INT = 0x04
|
|
103
|
+
FLAT_FLOAT = 0x05
|
|
104
|
+
FLAT_FALSE = 0x06
|
|
105
|
+
FLAT_TRUE = 0x07
|
|
106
|
+
FLAT_DT = 0x08 # ..0x0B: offset, local-datetime, date, local-time
|
|
107
|
+
|
|
108
|
+
def load_flat(handle)
|
|
109
|
+
bufp = FFI::MemoryPointer.new(:pointer)
|
|
110
|
+
lenp = FFI::MemoryPointer.new(:size_t)
|
|
111
|
+
st = Lib.teptris_document_flatten(handle, bufp, lenp)
|
|
112
|
+
raise Error, "flatten failed" unless st == Teptris::TEPTRIS_OK
|
|
113
|
+
|
|
114
|
+
buf = bufp.read_pointer
|
|
115
|
+
begin
|
|
116
|
+
data = buf.get_bytes(0, lenp.read_uint64)
|
|
117
|
+
value, = decode_flat(data, 0)
|
|
118
|
+
value
|
|
119
|
+
ensure
|
|
120
|
+
Lib.teptris_flatten_free(buf)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def decode_flat(d, pos)
|
|
125
|
+
case d.getbyte(pos)
|
|
126
|
+
when FLAT_TABLE
|
|
127
|
+
n = d.unpack1("L<", offset: pos + 1)
|
|
128
|
+
pos += 5
|
|
129
|
+
h = {}
|
|
130
|
+
n.times do
|
|
131
|
+
kl = d.unpack1("L<", offset: pos)
|
|
132
|
+
pos += 4
|
|
133
|
+
k = d.byteslice(pos, kl).force_encoding(Encoding::UTF_8)
|
|
134
|
+
pos += kl
|
|
135
|
+
v, pos = decode_flat(d, pos)
|
|
136
|
+
h[k] = v
|
|
137
|
+
end
|
|
138
|
+
[h, pos]
|
|
139
|
+
when FLAT_ARRAY
|
|
140
|
+
n = d.unpack1("L<", offset: pos + 1)
|
|
141
|
+
pos += 5
|
|
142
|
+
a = Array.new(n)
|
|
143
|
+
n.times do |i|
|
|
144
|
+
a[i], pos = decode_flat(d, pos)
|
|
145
|
+
end
|
|
146
|
+
[a, pos]
|
|
147
|
+
when FLAT_STRING
|
|
148
|
+
l = d.unpack1("L<", offset: pos + 1)
|
|
149
|
+
pos += 5
|
|
150
|
+
[d.byteslice(pos, l).force_encoding(Encoding::UTF_8), pos + l]
|
|
151
|
+
when FLAT_INT
|
|
152
|
+
[d.unpack1("q<", offset: pos + 1), pos + 9]
|
|
153
|
+
when FLAT_FLOAT
|
|
154
|
+
[d.unpack1("E", offset: pos + 1), pos + 9]
|
|
155
|
+
when FLAT_FALSE then [false, pos + 1]
|
|
156
|
+
when FLAT_TRUE then [true, pos + 1]
|
|
157
|
+
when FLAT_DT, FLAT_DT + 1, FLAT_DT + 2, FLAT_DT + 3
|
|
158
|
+
kind = d.getbyte(pos)
|
|
159
|
+
year = d.unpack1("q<", offset: pos + 1)
|
|
160
|
+
mon = d.getbyte(pos + 9)
|
|
161
|
+
day = d.getbyte(pos + 10)
|
|
162
|
+
hour = d.getbyte(pos + 11)
|
|
163
|
+
min = d.getbyte(pos + 12)
|
|
164
|
+
sec = d.getbyte(pos + 13)
|
|
165
|
+
nsec = d.unpack1("L<", offset: pos + 14)
|
|
166
|
+
off = d.unpack1("q<", offset: pos + 18)
|
|
167
|
+
[flat_datetime(kind, year, mon, day, hour, min, sec, nsec, off),
|
|
168
|
+
pos + 26]
|
|
169
|
+
else
|
|
170
|
+
raise Error, "corrupt flat buffer at #{pos}"
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def flat_datetime(kind, y, mon, day, hour, min, sec, nsec, off)
|
|
175
|
+
return flat_datetime_string(kind, y, mon, day, hour, min, sec, nsec, off) if @mode == 1
|
|
176
|
+
|
|
177
|
+
rational = Rational(sec * 1_000_000_000 + nsec, 1_000_000_000)
|
|
178
|
+
case kind
|
|
179
|
+
when FLAT_DT
|
|
180
|
+
check_permitted!(Time)
|
|
181
|
+
Time.new(y, mon, day, hour, min, rational, off)
|
|
182
|
+
when FLAT_DT + 1
|
|
183
|
+
check_permitted!(Time)
|
|
184
|
+
Time.local(y, mon, day, hour, min, rational)
|
|
185
|
+
when FLAT_DT + 2
|
|
186
|
+
check_permitted!(Date)
|
|
187
|
+
Date.new(y, mon, day)
|
|
188
|
+
else
|
|
189
|
+
s = format("%02d:%02d:%02d", hour, min, sec)
|
|
190
|
+
s << "." << format("%09d", nsec).sub(/0+\z/, "") if nsec.positive?
|
|
191
|
+
s
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def check_permitted!(klass)
|
|
196
|
+
permitted = @permitted
|
|
197
|
+
return if permitted.nil? || permitted.include?(klass)
|
|
198
|
+
|
|
199
|
+
raise Error,
|
|
200
|
+
"value materializes #{klass}, which is not in " \
|
|
201
|
+
"permitted_classes (use datetime_policy: :string to keep " \
|
|
202
|
+
"datetimes as strings)"
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def flat_datetime_string(kind, y, mon, day, hour, min, sec, nsec, off)
|
|
206
|
+
case kind
|
|
207
|
+
when FLAT_DT + 2 then return format("%04d-%02d-%02d", y, mon, day)
|
|
208
|
+
when FLAT_DT + 3 then s = +""
|
|
209
|
+
else s = +(format("%04d-%02d-%02dT", y, mon, day))
|
|
210
|
+
end
|
|
211
|
+
s << format("%02d:%02d:%02d", hour, min, sec)
|
|
212
|
+
if nsec.positive?
|
|
213
|
+
s << "." << format("%09d", nsec).sub(/0+\z/, "")
|
|
214
|
+
end
|
|
215
|
+
case kind
|
|
216
|
+
when FLAT_DT
|
|
217
|
+
off.zero? ? s << "Z" : s << format("%+03d:%02d", off / 3600, (off % 3600).abs / 60)
|
|
218
|
+
end
|
|
219
|
+
s
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# ---- dump -----------------------------------------------------------
|
|
223
|
+
|
|
224
|
+
def emit_table(hash, out, prefix)
|
|
225
|
+
hash.each do |k, v|
|
|
226
|
+
next if table?(v) || aot?(v)
|
|
227
|
+
|
|
228
|
+
out << emit_key(k) << " = " << emit_value(v) << "\n"
|
|
229
|
+
end
|
|
230
|
+
hash.each do |k, v|
|
|
231
|
+
next unless table?(v) || aot?(v)
|
|
232
|
+
|
|
233
|
+
path = prefix ? "#{prefix}.#{emit_key(k)}" : emit_key(k)
|
|
234
|
+
if aot?(v)
|
|
235
|
+
v.each do |item|
|
|
236
|
+
out << "[[" << path << "]]\n"
|
|
237
|
+
emit_table(item, out, path)
|
|
238
|
+
end
|
|
239
|
+
else
|
|
240
|
+
out << "[" << path << "]\n"
|
|
241
|
+
emit_table(v, out, path)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def table?(v)
|
|
247
|
+
v.is_a?(Hash)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def aot?(v)
|
|
251
|
+
v.is_a?(Array) && !v.empty? && v.all? { |e| e.is_a?(Hash) }
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def emit_key(k)
|
|
255
|
+
k = k.to_s
|
|
256
|
+
if /\A[A-Za-z0-9_-]+\z/.match?(k)
|
|
257
|
+
k
|
|
258
|
+
elsif !k.include?("'") && !k.each_char.any? { |c| c.ord < 0x20 }
|
|
259
|
+
"'#{k}'"
|
|
260
|
+
else
|
|
261
|
+
"\"#{escape_basic(k)}\""
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
BASIC_ESCAPES = {
|
|
266
|
+
"\\" => "\\\\\\\\", # \ -> \\
|
|
267
|
+
"\"" => "\\\"", "\b" => "\\b", "\f" => "\\f",
|
|
268
|
+
"\n" => "\\n", "\r" => "\\r", "\t" => "\\t"
|
|
269
|
+
}.freeze
|
|
270
|
+
|
|
271
|
+
def escape_basic(s)
|
|
272
|
+
s.gsub(/[\\\"\b\f\n\r\t]/) { |c| BASIC_ESCAPES[c] }
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def emit_value(v)
|
|
276
|
+
case v
|
|
277
|
+
when String
|
|
278
|
+
if !v.include?("'") && !v.each_char.any? { |c| c.ord < 0x20 }
|
|
279
|
+
"'#{v}'"
|
|
280
|
+
else
|
|
281
|
+
"\"#{escape_basic(v)}\""
|
|
282
|
+
end
|
|
283
|
+
when Integer then v.to_s
|
|
284
|
+
when Float
|
|
285
|
+
return v.to_s if v.finite?
|
|
286
|
+
|
|
287
|
+
v.nan? ? "nan" : (v.positive? ? "inf" : "-inf")
|
|
288
|
+
when TrueClass then "true"
|
|
289
|
+
when FalseClass then "false"
|
|
290
|
+
when Time
|
|
291
|
+
base = v.strftime("%Y-%m-%dT%H:%M:%S")
|
|
292
|
+
frac = v.strftime("%N").sub(/0+\z/, "")
|
|
293
|
+
base << "." << frac unless frac.empty?
|
|
294
|
+
base << tz(v)
|
|
295
|
+
when Date then v.iso8601
|
|
296
|
+
when Array then "[#{v.map { |e| emit_value(e) }.join(', ')}]"
|
|
297
|
+
when Hash
|
|
298
|
+
"{#{v.map { |k, e| "#{emit_key(k)} = #{emit_value(e)}" }.join(', ')}}"
|
|
299
|
+
else raise Error, "cannot dump #{v.class}"
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def tz(time)
|
|
304
|
+
off = time.utc_offset
|
|
305
|
+
return "Z" if off.zero?
|
|
306
|
+
|
|
307
|
+
sign = off.negative? ? "-" : "+"
|
|
308
|
+
off = -off if off.negative?
|
|
309
|
+
format("%s%02d:%02d", sign, off / 3600, (off % 3600) / 60)
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
data/lib/teptris.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: teptris
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: aarch64-linux
|
|
6
|
+
authors:
|
|
7
|
+
- teptris contributors
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-09-13 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: ffi
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.15'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.15'
|
|
27
|
+
description: An FFI binding over libteptris, a C11 TOML 1.0 parser/emitter. API shape
|
|
28
|
+
mirrors the tomlib gem.
|
|
29
|
+
email:
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- lib/libteptris.so
|
|
35
|
+
- lib/teptris.rb
|
|
36
|
+
- lib/teptris/error.rb
|
|
37
|
+
- lib/teptris/lib.rb
|
|
38
|
+
- lib/teptris/toml.rb
|
|
39
|
+
- lib/teptris/version.rb
|
|
40
|
+
homepage: https://github.com/leptris/teptris-ruby
|
|
41
|
+
licenses:
|
|
42
|
+
- MIT
|
|
43
|
+
metadata: {}
|
|
44
|
+
post_install_message:
|
|
45
|
+
rdoc_options: []
|
|
46
|
+
require_paths:
|
|
47
|
+
- lib
|
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '3.0'
|
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0'
|
|
58
|
+
requirements: []
|
|
59
|
+
rubygems_version: 3.5.22
|
|
60
|
+
signing_key:
|
|
61
|
+
specification_version: 4
|
|
62
|
+
summary: TOML for Ruby at libleptris speed (FFI, no C extension)
|
|
63
|
+
test_files: []
|