teptris 0.2.52 → 0.2.54
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 +4 -4
- data/Steepfile +10 -0
- data/ext/teptris_ext/materialize.c +81 -56
- data/lib/teptris/descriptor.rb +2 -0
- data/lib/teptris/toml.rb +4 -0
- data/lib/teptris/version.rb +1 -1
- data/sig/teptris.rbs +131 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d87bfa72c18905691d707f6025a6a38c50145e3b3fbdd852ae684a23b02cf5de
|
|
4
|
+
data.tar.gz: da1577dbc5917511ea6013c686b1ae9e33cdc8e344af69bbd73f884d9e658814
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3207652a5292daeafb0f790cb91da4497f9f83d860dc13cdbef03c0fe8d728daa69fd5e012cfd529b6a678e14298c9af1e6e9c5fd36715a74590922ccb336e02
|
|
7
|
+
data.tar.gz: 0e193983d8e3913b8b23c4d337fd6f1874cb8992fd7d28a82f7dddceba96d93a1038ec1cff203ac437281ab2b9c44a853092b54caefb669cb8bbfbcfeab896d0
|
data/Steepfile
ADDED
|
@@ -256,28 +256,6 @@ static void *parse_without_gvl(void *p)
|
|
|
256
256
|
return NULL;
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
static teptris_document *parse_or_raise(VALUE str) {
|
|
260
|
-
teptris_document *doc = NULL;
|
|
261
|
-
/* frozen strings cannot take the tmp lock (ruby 4.0 raises
|
|
262
|
-
* FrozenError - chilled literals); a dup is movable-page-safe the
|
|
263
|
-
* same way, at one input copy for frozen callers only */
|
|
264
|
-
volatile VALUE pin = OBJ_FROZEN(str) ? rb_str_dup(str) : str;
|
|
265
|
-
rb_str_locktmp(pin);
|
|
266
|
-
struct gvl_parse_arg arg = {RSTRING_PTR(pin), (size_t)RSTRING_LEN(pin),
|
|
267
|
-
&doc, TEPTRIS_OK};
|
|
268
|
-
rb_thread_call_without_gvl(parse_without_gvl, &arg, RUBY_UBF_IO, NULL);
|
|
269
|
-
rb_str_unlocktmp(pin);
|
|
270
|
-
teptris_status st = arg.st;
|
|
271
|
-
if (st != TEPTRIS_OK) {
|
|
272
|
-
const teptris_error *e = teptris_document_error(doc);
|
|
273
|
-
VALUE ex = rb_exc_new(eParseError, e->message, (long)strlen(e->message));
|
|
274
|
-
rb_iv_set(ex, "@line", SIZET2NUM(e->line));
|
|
275
|
-
rb_iv_set(ex, "@column", SIZET2NUM(e->column));
|
|
276
|
-
teptris_document_free(doc);
|
|
277
|
-
rb_exc_raise(ex);
|
|
278
|
-
}
|
|
279
|
-
return doc;
|
|
280
|
-
}
|
|
281
259
|
|
|
282
260
|
static VALUE ext_load(int argc, VALUE *argv, VALUE self) {
|
|
283
261
|
VALUE str, opts;
|
|
@@ -292,11 +270,29 @@ static VALUE ext_load(int argc, VALUE *argv, VALUE self) {
|
|
|
292
270
|
if (RTEST(ft)) flags |= FMT_FORBID_TIME;
|
|
293
271
|
if (RTEST(fd)) flags |= FMT_FORBID_DATE;
|
|
294
272
|
}
|
|
295
|
-
|
|
273
|
+
/* the parse is pure C over a private copy, GVL-free; the copy
|
|
274
|
+
* must outlive materialization - the document's strings are
|
|
275
|
+
* zero-copy views into it (a real UAF on glibc when freed early) */
|
|
276
|
+
long len = RSTRING_LEN(str);
|
|
277
|
+
char *cbuf = ALLOC_N(char, (size_t)len + 1);
|
|
278
|
+
memcpy(cbuf, RSTRING_PTR(str), (size_t)len);
|
|
279
|
+
teptris_document *doc = NULL;
|
|
280
|
+
struct gvl_parse_arg arg = {cbuf, (size_t)len, &doc, TEPTRIS_OK};
|
|
281
|
+
rb_thread_call_without_gvl(parse_without_gvl, &arg, RUBY_UBF_IO, NULL);
|
|
282
|
+
if (arg.st != TEPTRIS_OK) {
|
|
283
|
+
const teptris_error *e = teptris_document_error(doc);
|
|
284
|
+
VALUE ex = rb_exc_new(eParseError, e->message, (long)strlen(e->message));
|
|
285
|
+
rb_iv_set(ex, "@line", SIZET2NUM(e->line));
|
|
286
|
+
rb_iv_set(ex, "@column", SIZET2NUM(e->column));
|
|
287
|
+
xfree(cbuf);
|
|
288
|
+
teptris_document_free(doc);
|
|
289
|
+
rb_exc_raise(ex);
|
|
290
|
+
}
|
|
296
291
|
keycache kc;
|
|
297
292
|
kc_init(&kc);
|
|
298
293
|
VALUE out = obj_from_node(teptris_document_root(doc), flags, &kc);
|
|
299
294
|
kc_free(&kc);
|
|
295
|
+
xfree(cbuf);
|
|
300
296
|
teptris_document_free(doc);
|
|
301
297
|
return out;
|
|
302
298
|
}
|
|
@@ -741,7 +737,8 @@ static VALUE cLazyOwner, cLazyValue;
|
|
|
741
737
|
|
|
742
738
|
typedef struct {
|
|
743
739
|
teptris_document *doc;
|
|
744
|
-
VALUE input; /*
|
|
740
|
+
VALUE input; /* single-doc path: owned frozen copy (GC-marked) */
|
|
741
|
+
char *buf; /* batch path: owned input copy the doc's views use */
|
|
745
742
|
} lazy_owner;
|
|
746
743
|
|
|
747
744
|
typedef struct {
|
|
@@ -752,12 +749,18 @@ typedef struct {
|
|
|
752
749
|
static void lazy_owner_free(void *p) {
|
|
753
750
|
lazy_owner *o = (lazy_owner *)p;
|
|
754
751
|
if (o->doc != NULL) teptris_document_free(o->doc);
|
|
752
|
+
if (o->buf != NULL) xfree(o->buf);
|
|
755
753
|
xfree(o);
|
|
756
754
|
}
|
|
757
755
|
static size_t lazy_owner_size(const void *p) { return sizeof(lazy_owner); }
|
|
756
|
+
static void lazy_owner_mark(void *p)
|
|
757
|
+
{
|
|
758
|
+
lazy_owner *o = (lazy_owner *)p;
|
|
759
|
+
if (o->input) rb_gc_mark(o->input); /* roots the single-path copy */
|
|
760
|
+
}
|
|
758
761
|
static const rb_data_type_t lazy_owner_type = {
|
|
759
762
|
"TeptrisExt/LazyOwner",
|
|
760
|
-
{
|
|
763
|
+
{lazy_owner_mark, lazy_owner_free, lazy_owner_size, NULL, 0},
|
|
761
764
|
NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY};
|
|
762
765
|
|
|
763
766
|
static void lazy_value_mark(void *p) {
|
|
@@ -792,7 +795,7 @@ static VALUE ext_load_lazy(VALUE self, VALUE toml) {
|
|
|
792
795
|
VALUE owner = TypedData_Make_Struct(cLazyOwner, lazy_owner,
|
|
793
796
|
&lazy_owner_type, o);
|
|
794
797
|
o->doc = NULL;
|
|
795
|
-
o->input = rb_str_new_frozen(toml); /*
|
|
798
|
+
o->input = rb_str_new_frozen(toml); /* owned frozen copy */
|
|
796
799
|
teptris_status st = teptris_parse(RSTRING_PTR(o->input),
|
|
797
800
|
(size_t)RSTRING_LEN(o->input),
|
|
798
801
|
NULL, &o->doc);
|
|
@@ -973,25 +976,53 @@ static unsigned flags_from_opts(VALUE opts) {
|
|
|
973
976
|
/* Parse-only batch (returns an Array of Lazy wrappers, one per doc):
|
|
974
977
|
* eager parse, deferred materialization. Same per-doc error semantics
|
|
975
978
|
* as ext_load_lazy. */
|
|
979
|
+
struct batch_parse_arg {
|
|
980
|
+
const char **data;
|
|
981
|
+
size_t *lens;
|
|
982
|
+
size_t n;
|
|
983
|
+
teptris_document **docs;
|
|
984
|
+
teptris_status *statuses;
|
|
985
|
+
teptris_status batch;
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
static void *batch_parse_without_gvl(void *p)
|
|
989
|
+
{
|
|
990
|
+
struct batch_parse_arg *a = (struct batch_parse_arg *)p;
|
|
991
|
+
a->batch = teptris_parse_batch(a->data, a->lens, a->n, NULL,
|
|
992
|
+
a->docs, a->statuses);
|
|
993
|
+
return NULL;
|
|
994
|
+
}
|
|
995
|
+
|
|
976
996
|
static VALUE ext_load_lazy_batch(VALUE self, VALUE strings) {
|
|
977
997
|
Check_Type(strings, T_ARRAY);
|
|
978
998
|
long n = RARRAY_LEN(strings);
|
|
979
999
|
if (n == 0) return rb_ary_new();
|
|
980
1000
|
batch_scratch *s = batch_scratch_alloc(n);
|
|
981
1001
|
if (s == NULL) rb_raise(eError, "out of memory batching %ld documents", n);
|
|
1002
|
+
/* the batch parse is pure C: pin every input (one tmp lock per
|
|
1003
|
+
* string - repeated objects dup; frozen strings cannot take the
|
|
1004
|
+
* lock, yet compaction can move them) and release the GVL for the
|
|
1005
|
+
* whole parse */
|
|
1006
|
+
/* the batch parse is pure C over private copies: a Ruby-string
|
|
1007
|
+
* buffer can move under a concurrent compacting GC, and locktmp
|
|
1008
|
+
* does not pin on every platform - copies are C memory, immovable
|
|
1009
|
+
* by construction. Each LazyOwner owns its copy (freed with the
|
|
1010
|
+
* owner): the lazy nodes view these buffers until materialized. */
|
|
1011
|
+
char **bufs = ALLOC_N(char *, n);
|
|
982
1012
|
for (long i = 0; i < n; i++) {
|
|
983
1013
|
VALUE str = rb_ary_entry(strings, i);
|
|
984
1014
|
StringValue(str); /* raises TypeError if not coercible */
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
s->docs, s->statuses);
|
|
991
|
-
if (batch != TEPTRIS_OK) {
|
|
992
|
-
batch_scratch_free(s);
|
|
993
|
-
rb_raise(eError, "batch parse failed (status %d)", (int)batch);
|
|
1015
|
+
long len = RSTRING_LEN(str);
|
|
1016
|
+
bufs[i] = ALLOC_N(char, (size_t)len + 1);
|
|
1017
|
+
memcpy(bufs[i], RSTRING_PTR(str), (size_t)len);
|
|
1018
|
+
s->data[i] = bufs[i];
|
|
1019
|
+
s->lens[i] = (size_t)len;
|
|
994
1020
|
}
|
|
1021
|
+
struct batch_parse_arg arg = {s->data, s->lens, (size_t)n,
|
|
1022
|
+
s->docs, s->statuses, TEPTRIS_OK};
|
|
1023
|
+
rb_thread_call_without_gvl(batch_parse_without_gvl, &arg,
|
|
1024
|
+
RUBY_UBF_IO, NULL);
|
|
1025
|
+
teptris_status batch = arg.batch;
|
|
995
1026
|
long first_fail = -1;
|
|
996
1027
|
for (long i = 0; i < n; i++) {
|
|
997
1028
|
if (s->statuses[i] != TEPTRIS_OK && first_fail == -1) first_fail = i;
|
|
@@ -1012,7 +1043,7 @@ static VALUE ext_load_lazy_batch(VALUE self, VALUE strings) {
|
|
|
1012
1043
|
VALUE owner = TypedData_Make_Struct(cLazyOwner, lazy_owner,
|
|
1013
1044
|
&lazy_owner_type, o);
|
|
1014
1045
|
o->doc = s->docs[i];
|
|
1015
|
-
o->
|
|
1046
|
+
o->buf = bufs[i]; /* the owner owns this copy */
|
|
1016
1047
|
rb_ary_push(out, lazy_wrap(owner, teptris_document_root(s->docs[i])));
|
|
1017
1048
|
}
|
|
1018
1049
|
batch_scratch_free(s);
|
|
@@ -1053,35 +1084,29 @@ static VALUE ext_load_slice(int argc, VALUE *argv, VALUE self) {
|
|
|
1053
1084
|
if (n == 0) return rb_ary_new();
|
|
1054
1085
|
unsigned flags = flags_from_opts(opts);
|
|
1055
1086
|
|
|
1056
|
-
|
|
1087
|
+
/* the GVL-free parse reads private copies: a Ruby-string buffer
|
|
1088
|
+
* can move under a concurrent compacting GC, and locktmp does not
|
|
1089
|
+
* pin on every platform (windows ruby 3.3 parsed garbage). Copies
|
|
1090
|
+
* are C memory - immovable by construction. Freed after
|
|
1091
|
+
* materialization (the docs view them until then). */
|
|
1057
1092
|
const char **data = ALLOC_N(const char *, n);
|
|
1058
1093
|
size_t *lens = ALLOC_N(size_t, n);
|
|
1059
1094
|
teptris_document **docs = ALLOC_N(teptris_document *, n);
|
|
1060
1095
|
teptris_status *stats = ALLOC_N(teptris_status, n);
|
|
1061
|
-
|
|
1062
|
-
* get a dup before pinning (frozen inputs dup for the same reason
|
|
1063
|
-
* - they cannot take the lock, yet compaction can move them) */
|
|
1064
|
-
VALUE seen = rb_hash_new();
|
|
1096
|
+
char **bufs = ALLOC_N(char *, n);
|
|
1065
1097
|
long i;
|
|
1066
1098
|
for (i = 0; i < n; i++) {
|
|
1067
1099
|
VALUE str = rb_ary_entry(strs, i);
|
|
1068
1100
|
StringValue(str);
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
if (OBJ_FROZEN(str)) str = rb_str_dup(str);
|
|
1075
|
-
}
|
|
1076
|
-
pins[i] = str;
|
|
1077
|
-
rb_str_locktmp(pins[i]);
|
|
1078
|
-
data[i] = RSTRING_PTR(pins[i]);
|
|
1079
|
-
lens[i] = (size_t)RSTRING_LEN(pins[i]);
|
|
1101
|
+
long len = RSTRING_LEN(str);
|
|
1102
|
+
bufs[i] = ALLOC_N(char, (size_t)len + 1);
|
|
1103
|
+
memcpy(bufs[i], RSTRING_PTR(str), (size_t)len);
|
|
1104
|
+
data[i] = bufs[i];
|
|
1105
|
+
lens[i] = (size_t)len;
|
|
1080
1106
|
}
|
|
1081
1107
|
struct slice_parse_arg arg = {n, data, lens, docs, stats};
|
|
1082
1108
|
rb_thread_call_without_gvl(slice_parse_without_gvl, &arg,
|
|
1083
1109
|
RUBY_UBF_IO, NULL);
|
|
1084
|
-
for (i = 0; i < n; i++) rb_str_unlocktmp(pins[i]);
|
|
1085
1110
|
|
|
1086
1111
|
VALUE out = rb_ary_new_capa(n);
|
|
1087
1112
|
keycache kc;
|
|
@@ -1091,7 +1116,7 @@ static VALUE ext_load_slice(int argc, VALUE *argv, VALUE self) {
|
|
|
1091
1116
|
const char *msg = "parse failed (out of memory)";
|
|
1092
1117
|
VALUE ex = rb_exc_new(eParseError, msg, (long)strlen(msg));
|
|
1093
1118
|
kc_free(&kc);
|
|
1094
|
-
xfree(
|
|
1119
|
+
xfree(data); xfree(lens); xfree(docs); xfree(stats);
|
|
1095
1120
|
rb_exc_raise(ex);
|
|
1096
1121
|
}
|
|
1097
1122
|
const teptris_error *e = teptris_document_error(docs[i]);
|
|
@@ -1103,7 +1128,7 @@ static VALUE ext_load_slice(int argc, VALUE *argv, VALUE self) {
|
|
|
1103
1128
|
long j;
|
|
1104
1129
|
for (j = i; j < n; j++) teptris_document_free(docs[j]);
|
|
1105
1130
|
kc_free(&kc);
|
|
1106
|
-
xfree(
|
|
1131
|
+
xfree(data); xfree(lens); xfree(docs); xfree(stats);
|
|
1107
1132
|
rb_exc_raise(ex);
|
|
1108
1133
|
}
|
|
1109
1134
|
}
|
|
@@ -1113,7 +1138,7 @@ static VALUE ext_load_slice(int argc, VALUE *argv, VALUE self) {
|
|
|
1113
1138
|
teptris_document_free(docs[i]);
|
|
1114
1139
|
}
|
|
1115
1140
|
kc_free(&kc);
|
|
1116
|
-
xfree(
|
|
1141
|
+
xfree(data); xfree(lens); xfree(docs); xfree(stats);
|
|
1117
1142
|
return out;
|
|
1118
1143
|
}
|
|
1119
1144
|
|
data/lib/teptris/descriptor.rb
CHANGED
|
@@ -32,7 +32,9 @@ class Teptris::Descriptor
|
|
|
32
32
|
# siblings that follow a :nested child into the sub-plan's range —
|
|
33
33
|
# the 0.2.29 bug (every array-of-tables element grew stray nil
|
|
34
34
|
# rows).
|
|
35
|
+
# @type var plans: Array[Hash[Symbol, untyped]]
|
|
35
36
|
plans = []
|
|
37
|
+
# @type var index_of: Hash[Integer, Integer]
|
|
36
38
|
index_of = {}
|
|
37
39
|
collect = lambda do |t|
|
|
38
40
|
unless index_of.key?(t.object_id)
|
data/lib/teptris/toml.rb
CHANGED
|
@@ -25,6 +25,7 @@ module Teptris
|
|
|
25
25
|
unless %i[native string].include?(datetime_policy)
|
|
26
26
|
raise ArgumentError, "datetime_policy must be :native or :string"
|
|
27
27
|
end
|
|
28
|
+
# @type var opts: Hash[Symbol, untyped]
|
|
28
29
|
opts = {}
|
|
29
30
|
opts[:string_datetimes] = true if datetime_policy == :string
|
|
30
31
|
if permitted_classes && datetime_policy == :native
|
|
@@ -69,6 +70,7 @@ module Teptris
|
|
|
69
70
|
# Repeated objects are dup'd once each HERE: a repeat landing in
|
|
70
71
|
# two slices would double-lock across threads (the slice-level
|
|
71
72
|
# guard cannot see across slices); frozen dup'ing is C-side.
|
|
73
|
+
# @type var seen: Hash[Integer, bool]
|
|
72
74
|
seen = {}
|
|
73
75
|
tomls = tomls.map do |s|
|
|
74
76
|
next s.dup if seen[s.object_id]
|
|
@@ -77,6 +79,7 @@ module Teptris
|
|
|
77
79
|
end
|
|
78
80
|
per = (n.to_f / threads).ceil
|
|
79
81
|
results = Array.new(n)
|
|
82
|
+
# @type var first_error: [Integer, untyped]?
|
|
80
83
|
first_error = nil
|
|
81
84
|
mutex = Mutex.new
|
|
82
85
|
threads.times.map do |ti|
|
|
@@ -157,6 +160,7 @@ module Teptris
|
|
|
157
160
|
end
|
|
158
161
|
|
|
159
162
|
def _safe_load_opts(safe_load, datetime_policy)
|
|
163
|
+
# @type var opts: Hash[Symbol, untyped]
|
|
160
164
|
opts = {}
|
|
161
165
|
opts[:string_datetimes] = true if datetime_policy == :string
|
|
162
166
|
if safe_load && datetime_policy == :native
|
data/lib/teptris/version.rb
CHANGED
data/sig/teptris.rbs
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
module Teptris
|
|
2
|
+
VERSION: String
|
|
3
|
+
|
|
4
|
+
# mirrored from the engine's teptris_status (lib/teptris.rb)
|
|
5
|
+
TEPTRIS_OK: Integer
|
|
6
|
+
|
|
7
|
+
class Error < StandardError
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class ParseError < Error
|
|
11
|
+
attr_reader line: Integer
|
|
12
|
+
attr_reader column: Integer
|
|
13
|
+
|
|
14
|
+
def initialize: (String message, ?Integer line, ?Integer column) -> void
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module TOML
|
|
18
|
+
VERSION: String
|
|
19
|
+
|
|
20
|
+
# Eager load: String -> Hash with String keys. Datetime contract
|
|
21
|
+
# (the tomlib shape): Time with zone for offset datetimes, local
|
|
22
|
+
# Time for local datetimes, Date for dates, "HH:MM:SS" String for
|
|
23
|
+
# local times.
|
|
24
|
+
def self.load: (String toml) -> Hash[String, untyped]
|
|
25
|
+
|
|
26
|
+
def self.load_file: (String path) -> Hash[String, untyped]
|
|
27
|
+
|
|
28
|
+
def self.safe_load: (String toml, ?permitted_classes: Array[Class]?,
|
|
29
|
+
?datetime_policy: :native | :string)
|
|
30
|
+
-> Hash[String, untyped]
|
|
31
|
+
|
|
32
|
+
# One parse; host objects materialize only along accessed paths.
|
|
33
|
+
def self.load_lazy: (String toml) -> TeptrisExt::LazyValue
|
|
34
|
+
|
|
35
|
+
def self.load_batch: (Array[String] tomls, ?safe_load: Array[Class]?,
|
|
36
|
+
?datetime_policy: :native | :string,
|
|
37
|
+
?threads: Integer)
|
|
38
|
+
-> Array[Hash[String, untyped]]
|
|
39
|
+
|
|
40
|
+
def self.load_lazy_batch: (Array[String] tomls)
|
|
41
|
+
-> Array[TeptrisExt::LazyValue]
|
|
42
|
+
|
|
43
|
+
def self.load_files: (Array[String] paths, ?safe_load: Array[Class]?,
|
|
44
|
+
?datetime_policy: :native | :string)
|
|
45
|
+
-> Array[Hash[String, untyped]]
|
|
46
|
+
|
|
47
|
+
def self.load_schema: (String toml, Descriptor descriptor)
|
|
48
|
+
-> Hash[String, untyped]
|
|
49
|
+
|
|
50
|
+
def self.dump: (untyped obj) -> String
|
|
51
|
+
|
|
52
|
+
def self.engine_version: () -> String
|
|
53
|
+
|
|
54
|
+
def self._validate_batch!: (untyped input, untyped safe_load,
|
|
55
|
+
:native | :string datetime_policy,
|
|
56
|
+
?kind: Symbol) -> void
|
|
57
|
+
|
|
58
|
+
def self._safe_load_opts: (untyped safe_load,
|
|
59
|
+
:native | :string datetime_policy)
|
|
60
|
+
-> Hash[Symbol, untyped]?
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Tree-shaped schema descriptor: compile once with .build, then
|
|
64
|
+
# materialize documents against it with #walk — unplanned keys are
|
|
65
|
+
# never materialized (the py twin is teptris.Descriptor).
|
|
66
|
+
class Descriptor
|
|
67
|
+
KINDS: Hash[Symbol, Integer]
|
|
68
|
+
|
|
69
|
+
def self.build: (Hash[Symbol, untyped] tree) -> Descriptor
|
|
70
|
+
|
|
71
|
+
attr_reader rows: Array[[String, Integer, Integer]]
|
|
72
|
+
attr_reader first_row: Array[Integer]
|
|
73
|
+
|
|
74
|
+
def walk: (String toml) -> Hash[String, untyped]
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# The C extension's surface (defined in ext/teptris_ext). The gem's
|
|
79
|
+
# public API is Teptris::TOML; these module functions are the binding
|
|
80
|
+
# layer underneath it.
|
|
81
|
+
module TeptrisExt
|
|
82
|
+
# Lazy wrapper: one parse, scalars materialize on access, to_h/to_a
|
|
83
|
+
# flatten to the eager shapes.
|
|
84
|
+
class LazyValue
|
|
85
|
+
def []: (String key) -> (LazyValue | untyped)
|
|
86
|
+
| (Integer index) -> (LazyValue | untyped)
|
|
87
|
+
|
|
88
|
+
def at: (Integer index) -> (LazyValue | untyped)
|
|
89
|
+
|
|
90
|
+
def dig: (*String keys) -> (LazyValue | untyped)
|
|
91
|
+
|
|
92
|
+
def kind: () -> String
|
|
93
|
+
|
|
94
|
+
def size: () -> Integer
|
|
95
|
+
|
|
96
|
+
def each: () { (LazyValue | untyped) -> void } -> LazyValue
|
|
97
|
+
| () -> Enumerator[LazyValue | untyped, LazyValue]
|
|
98
|
+
|
|
99
|
+
def value: () -> untyped
|
|
100
|
+
|
|
101
|
+
def to_h: () -> Hash[String, untyped]
|
|
102
|
+
|
|
103
|
+
def to_a: () -> Array[untyped]
|
|
104
|
+
|
|
105
|
+
def ==: (untyped other) -> bool
|
|
106
|
+
|
|
107
|
+
include Enumerable[LazyValue | untyped]
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.load: (String toml, ?Hash[Symbol, untyped]? opts)
|
|
111
|
+
-> Hash[String, untyped]
|
|
112
|
+
|
|
113
|
+
def self.load_lazy: (String toml) -> LazyValue
|
|
114
|
+
|
|
115
|
+
def self.load_batch: (Array[String] tomls, Hash[Symbol, untyped]? opts)
|
|
116
|
+
-> Array[Hash[String, untyped]]
|
|
117
|
+
|
|
118
|
+
def self.load_slice: (Array[String] tomls, Hash[Symbol, untyped]? opts)
|
|
119
|
+
-> Array[Hash[String, untyped]]
|
|
120
|
+
|
|
121
|
+
def self.load_lazy_batch: (Array[String] tomls) -> Array[LazyValue]
|
|
122
|
+
|
|
123
|
+
def self.dump: (untyped obj) -> String
|
|
124
|
+
|
|
125
|
+
def self.engine_version: () -> String
|
|
126
|
+
|
|
127
|
+
def self.plan_build: (Array[[String, Integer, Integer]] rows,
|
|
128
|
+
Array[Integer] first_row) -> untyped
|
|
129
|
+
|
|
130
|
+
def self.plan_emit: (untyped handle, String toml) -> Hash[String, untyped]
|
|
131
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: teptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.54
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- teptris contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A native C extension over libteptris, a C99 TOML 1.1 parser/emitter.
|
|
14
14
|
API shape mirrors the tomlib gem.
|
|
@@ -18,6 +18,7 @@ extensions:
|
|
|
18
18
|
- ext/teptris_ext/extconf.rb
|
|
19
19
|
extra_rdoc_files: []
|
|
20
20
|
files:
|
|
21
|
+
- Steepfile
|
|
21
22
|
- ext/teptris_ext/engine/LICENSE.md
|
|
22
23
|
- ext/teptris_ext/engine/README.md
|
|
23
24
|
- ext/teptris_ext/engine/src/include/teptris/plan.h
|
|
@@ -56,6 +57,7 @@ files:
|
|
|
56
57
|
- lib/teptris/error.rb
|
|
57
58
|
- lib/teptris/toml.rb
|
|
58
59
|
- lib/teptris/version.rb
|
|
60
|
+
- sig/teptris.rbs
|
|
59
61
|
homepage: https://github.com/leptris/teptris-ruby
|
|
60
62
|
licenses:
|
|
61
63
|
- MIT
|