yerba 0.9.2-arm-linux-gnu → 0.10.0-arm-linux-gnu
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/README.md +34 -17
- data/exe/arm-linux-gnu/yerba +0 -0
- data/ext/yerba/include/yerba.h +56 -34
- data/ext/yerba/yerba.c +268 -186
- data/lib/yerba/3.2/yerba.so +0 -0
- data/lib/yerba/3.3/yerba.so +0 -0
- data/lib/yerba/3.4/yerba.so +0 -0
- data/lib/yerba/4.0/yerba.so +0 -0
- data/lib/yerba/collection.rb +4 -4
- data/lib/yerba/document.rb +134 -0
- data/lib/yerba/formatting.rb +1 -0
- data/lib/yerba/location.rb +8 -1
- data/lib/yerba/map.rb +16 -6
- data/lib/yerba/node.rb +41 -0
- data/lib/yerba/query_result.rb +33 -10
- data/lib/yerba/scalar.rb +29 -0
- data/lib/yerba/selector.rb +3 -1
- data/lib/yerba/sequence.rb +38 -33
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/src/commands/get.rs +12 -12
- data/rust/src/commands/init.rs +8 -8
- data/rust/src/commands/insert.rs +4 -18
- data/rust/src/commands/location.rs +2 -0
- data/rust/src/commands/mod.rs +34 -6
- data/rust/src/commands/move_item.rs +1 -1
- data/rust/src/commands/move_key.rs +8 -8
- data/rust/src/commands/rename.rs +1 -1
- data/rust/src/commands/selectors.rs +1 -1
- data/rust/src/commands/set.rs +14 -6
- data/rust/src/document/condition.rs +25 -25
- data/rust/src/document/delete.rs +57 -43
- data/rust/src/document/get.rs +91 -82
- data/rust/src/document/insert.rs +77 -77
- data/rust/src/document/mod.rs +138 -64
- data/rust/src/document/nodes.rs +162 -0
- data/rust/src/document/schema.rs +8 -8
- data/rust/src/document/set.rs +49 -26
- data/rust/src/document/sort.rs +54 -54
- data/rust/src/document/style.rs +50 -49
- data/rust/src/document/unique.rs +5 -5
- data/rust/src/error.rs +8 -4
- data/rust/src/ffi.rs +218 -106
- data/rust/src/json.rs +62 -2
- data/rust/src/lib.rs +2 -1
- data/rust/src/main.rs +2 -1
- data/rust/src/selector.rs +48 -7
- data/rust/src/syntax.rs +449 -56
- data/rust/src/validation.rs +5 -3
- data/rust/src/yerbafile.rs +124 -76
- metadata +3 -2
data/ext/yerba/yerba.c
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include <ruby.h>
|
|
2
2
|
#include <ruby/encoding.h>
|
|
3
|
+
#include <math.h>
|
|
3
4
|
#include <string.h>
|
|
4
5
|
#include "include/yerba.h"
|
|
5
6
|
|
|
@@ -48,9 +49,9 @@ static void check_result(YerbaResult result) {
|
|
|
48
49
|
VALUE message = make_utf8_string(result.error);
|
|
49
50
|
VALUE error_class = rb_eError;
|
|
50
51
|
|
|
51
|
-
if (strstr(result.error, "invalid
|
|
52
|
+
if (strstr(result.error, "invalid selector")) {
|
|
52
53
|
error_class = rb_ePathValidationError;
|
|
53
|
-
} else if (strstr(result.error, "
|
|
54
|
+
} else if (strstr(result.error, "selector not found") || strstr(result.error, "not a sequence")) {
|
|
54
55
|
error_class = rb_ePathNotFoundError;
|
|
55
56
|
} else if (strstr(result.error, "parse error")) {
|
|
56
57
|
error_class = rb_eParseError;
|
|
@@ -72,21 +73,23 @@ static VALUE typed_value_to_ruby(YerbaTypedValue typed_value) {
|
|
|
72
73
|
break;
|
|
73
74
|
|
|
74
75
|
case YERBA_VALUE_TYPE_BOOLEAN:
|
|
75
|
-
result =
|
|
76
|
-
strcmp(typed_value.text, "TRUE") == 0 || strcmp(typed_value.text, "yes") == 0 ||
|
|
77
|
-
strcmp(typed_value.text, "Yes") == 0 || strcmp(typed_value.text, "YES") == 0 ||
|
|
78
|
-
strcmp(typed_value.text, "on") == 0 || strcmp(typed_value.text, "On") == 0 ||
|
|
79
|
-
strcmp(typed_value.text, "ON") == 0 || strcmp(typed_value.text, "y") == 0 ||
|
|
80
|
-
strcmp(typed_value.text, "Y") == 0)
|
|
81
|
-
? Qtrue : Qfalse;
|
|
76
|
+
result = strcmp(typed_value.text, "true") == 0 ? Qtrue : Qfalse;
|
|
82
77
|
break;
|
|
83
78
|
|
|
84
79
|
case YERBA_VALUE_TYPE_INTEGER:
|
|
85
|
-
result = rb_cstr_to_inum(typed_value.text,
|
|
80
|
+
result = rb_cstr_to_inum(typed_value.text, 10, 0);
|
|
86
81
|
break;
|
|
87
82
|
|
|
88
83
|
case YERBA_VALUE_TYPE_FLOAT:
|
|
89
|
-
|
|
84
|
+
if (strcmp(typed_value.text, ".inf") == 0) {
|
|
85
|
+
result = rb_float_new(HUGE_VAL);
|
|
86
|
+
} else if (strcmp(typed_value.text, "-.inf") == 0) {
|
|
87
|
+
result = rb_float_new(-HUGE_VAL);
|
|
88
|
+
} else if (strcmp(typed_value.text, ".nan") == 0) {
|
|
89
|
+
result = rb_float_new(nan(""));
|
|
90
|
+
} else {
|
|
91
|
+
result = rb_float_new(rb_cstr_to_dbl(typed_value.text, 0));
|
|
92
|
+
}
|
|
90
93
|
break;
|
|
91
94
|
|
|
92
95
|
case YERBA_VALUE_TYPE_STRING:
|
|
@@ -116,12 +119,12 @@ static int should_proceed(struct Document *document, VALUE opts) {
|
|
|
116
119
|
VALUE v_condition = rb_hash_aref(opts, ID2SYM(rb_intern("condition")));
|
|
117
120
|
if (NIL_P(v_condition)) return 1;
|
|
118
121
|
|
|
119
|
-
VALUE
|
|
120
|
-
const char *
|
|
122
|
+
VALUE v_selector = rb_hash_aref(opts, ID2SYM(rb_intern("condition_path")));
|
|
123
|
+
const char *parent_selector = NIL_P(v_selector) ? "" : StringValueCStr(v_selector);
|
|
121
124
|
|
|
122
|
-
check_condition(StringValueCStr(v_condition),
|
|
125
|
+
check_condition(StringValueCStr(v_condition), parent_selector[0] != '\0');
|
|
123
126
|
|
|
124
|
-
return yerba_document_evaluate_condition(document,
|
|
127
|
+
return yerba_document_evaluate_condition(document, parent_selector, StringValueCStr(v_condition));
|
|
125
128
|
}
|
|
126
129
|
|
|
127
130
|
/* Document.new(path) */
|
|
@@ -199,19 +202,21 @@ static VALUE document_s_parse(VALUE klass, VALUE content) {
|
|
|
199
202
|
static VALUE location_to_ruby(YerbaLocation location) {
|
|
200
203
|
VALUE klass = rb_path2class("Yerba::Location");
|
|
201
204
|
|
|
202
|
-
return rb_funcall(klass, rb_intern("new"),
|
|
205
|
+
return rb_funcall(klass, rb_intern("new"), 8,
|
|
203
206
|
SIZET2NUM(location.start_line),
|
|
204
207
|
SIZET2NUM(location.start_column),
|
|
205
208
|
SIZET2NUM(location.end_line),
|
|
206
209
|
SIZET2NUM(location.end_column),
|
|
207
210
|
SIZET2NUM(location.start_offset),
|
|
208
|
-
SIZET2NUM(location.end_offset)
|
|
211
|
+
SIZET2NUM(location.end_offset),
|
|
212
|
+
SIZET2NUM(location.start_character_column),
|
|
213
|
+
SIZET2NUM(location.end_character_column)
|
|
209
214
|
);
|
|
210
215
|
}
|
|
211
216
|
|
|
212
217
|
/* Build a Yerba::Scalar, Map, Sequence, or nil from a YerbaGetResult.
|
|
213
218
|
Frees the result internally. */
|
|
214
|
-
static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE
|
|
219
|
+
static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE selector) {
|
|
215
220
|
if (result.error) {
|
|
216
221
|
VALUE message = make_utf8_string(result.error);
|
|
217
222
|
yerba_get_result_free(result);
|
|
@@ -239,18 +244,18 @@ static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE path)
|
|
|
239
244
|
VALUE kwargs = rb_hash_new();
|
|
240
245
|
rb_hash_aset(kwargs, ID2SYM(rb_intern("value")), value);
|
|
241
246
|
|
|
242
|
-
return rb_funcallv_kw(rb_path2class("Yerba::Scalar"), rb_intern("from_document"), 5, (VALUE[]){ self,
|
|
247
|
+
return rb_funcallv_kw(rb_path2class("Yerba::Scalar"), rb_intern("from_document"), 5, (VALUE[]){ self, selector, location, key, kwargs }, RB_PASS_KEYWORDS);
|
|
243
248
|
}
|
|
244
249
|
|
|
245
250
|
case NODE_TYPE_MAP:
|
|
246
251
|
yerba_get_result_free(result);
|
|
247
252
|
|
|
248
|
-
return rb_funcall(rb_path2class("Yerba::Map"), rb_intern("from_document"), 4, self,
|
|
253
|
+
return rb_funcall(rb_path2class("Yerba::Map"), rb_intern("from_document"), 4, self, selector, location, key);
|
|
249
254
|
|
|
250
255
|
case NODE_TYPE_SEQUENCE:
|
|
251
256
|
yerba_get_result_free(result);
|
|
252
257
|
|
|
253
|
-
return rb_funcall(rb_path2class("Yerba::Sequence"), rb_intern("from_document"), 4, self,
|
|
258
|
+
return rb_funcall(rb_path2class("Yerba::Sequence"), rb_intern("from_document"), 4, self, selector, location, key);
|
|
254
259
|
|
|
255
260
|
default:
|
|
256
261
|
yerba_get_result_free(result);
|
|
@@ -259,20 +264,20 @@ static VALUE node_from_get_result(YerbaGetResult result, VALUE self, VALUE path)
|
|
|
259
264
|
}
|
|
260
265
|
}
|
|
261
266
|
|
|
262
|
-
/* document[](
|
|
263
|
-
static VALUE document_bracket(VALUE self, VALUE
|
|
267
|
+
/* document[](selector) → Yerba::Scalar, Yerba::Map, Yerba::Sequence, Array, or nil */
|
|
268
|
+
static VALUE document_bracket(VALUE self, VALUE selector) {
|
|
264
269
|
struct Document *document = get_document(self);
|
|
265
270
|
char index_buffer[32];
|
|
266
271
|
|
|
267
|
-
if (RB_TYPE_P(
|
|
268
|
-
snprintf(index_buffer, sizeof(index_buffer), "[%ld]", FIX2LONG(
|
|
269
|
-
|
|
272
|
+
if (RB_TYPE_P(selector, T_FIXNUM)) {
|
|
273
|
+
snprintf(index_buffer, sizeof(index_buffer), "[%ld]", FIX2LONG(selector));
|
|
274
|
+
selector = rb_str_new_cstr(index_buffer);
|
|
270
275
|
}
|
|
271
276
|
|
|
272
|
-
const char *
|
|
277
|
+
const char *selector_string = StringValueCStr(selector);
|
|
273
278
|
|
|
274
|
-
if (yerba_selector_has_wildcard(
|
|
275
|
-
char *json = yerba_document_resolve_selectors(document,
|
|
279
|
+
if (yerba_selector_has_wildcard(selector_string)) {
|
|
280
|
+
char *json = yerba_document_resolve_selectors(document, selector_string);
|
|
276
281
|
|
|
277
282
|
if (!json) return rb_ary_new();
|
|
278
283
|
|
|
@@ -284,9 +289,9 @@ static VALUE document_bracket(VALUE self, VALUE path) {
|
|
|
284
289
|
VALUE array = rb_ary_new_capa(length);
|
|
285
290
|
|
|
286
291
|
for (long i = 0; i < length; i++) {
|
|
287
|
-
VALUE
|
|
288
|
-
YerbaGetResult result = yerba_document_get(document, StringValueCStr(
|
|
289
|
-
VALUE node = node_from_get_result(result, self,
|
|
292
|
+
VALUE concrete_selector = rb_ary_entry(resolved, i);
|
|
293
|
+
YerbaGetResult result = yerba_document_get(document, StringValueCStr(concrete_selector));
|
|
294
|
+
VALUE node = node_from_get_result(result, self, concrete_selector);
|
|
290
295
|
|
|
291
296
|
if (!NIL_P(node)) rb_ary_push(array, node);
|
|
292
297
|
}
|
|
@@ -294,29 +299,44 @@ static VALUE document_bracket(VALUE self, VALUE path) {
|
|
|
294
299
|
return array;
|
|
295
300
|
}
|
|
296
301
|
|
|
297
|
-
|
|
302
|
+
VALUE concrete_selector = selector;
|
|
303
|
+
|
|
304
|
+
if (strstr(selector_string, "[-") != NULL) {
|
|
305
|
+
char *json = yerba_document_resolve_selectors(document, selector_string);
|
|
306
|
+
|
|
307
|
+
if (json) {
|
|
308
|
+
VALUE json_string = make_utf8_string(json);
|
|
309
|
+
yerba_string_free(json);
|
|
310
|
+
|
|
311
|
+
VALUE resolved = rb_funcall(rb_path2class("JSON"), rb_intern("parse"), 1, json_string);
|
|
312
|
+
|
|
313
|
+
if (RARRAY_LEN(resolved) > 0) concrete_selector = rb_ary_entry(resolved, 0);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
YerbaGetResult result = yerba_document_get(document, StringValueCStr(selector));
|
|
298
318
|
|
|
299
|
-
return node_from_get_result(result, self,
|
|
319
|
+
return node_from_get_result(result, self, concrete_selector);
|
|
300
320
|
}
|
|
301
321
|
|
|
302
|
-
/* document.exists?(
|
|
303
|
-
static VALUE document_exists_p(VALUE self, VALUE
|
|
322
|
+
/* document.exists?(selector) */
|
|
323
|
+
static VALUE document_exists_p(VALUE self, VALUE selector) {
|
|
304
324
|
struct Document *document = get_document(self);
|
|
305
325
|
|
|
306
|
-
return yerba_document_exists(document, StringValueCStr(
|
|
326
|
+
return yerba_document_exists(document, StringValueCStr(selector)) ? Qtrue : Qfalse;
|
|
307
327
|
}
|
|
308
328
|
|
|
309
329
|
/* document.valid_selector?(selector) → true/false */
|
|
310
|
-
static VALUE document_valid_selector_p(VALUE self, VALUE
|
|
330
|
+
static VALUE document_valid_selector_p(VALUE self, VALUE selector) {
|
|
311
331
|
struct Document *document = get_document(self);
|
|
312
332
|
|
|
313
|
-
return yerba_document_valid_selector(document, StringValueCStr(
|
|
333
|
+
return yerba_document_valid_selector(document, StringValueCStr(selector)) ? Qtrue : Qfalse;
|
|
314
334
|
}
|
|
315
335
|
|
|
316
|
-
/* document.source(
|
|
317
|
-
static VALUE document_source(VALUE self, VALUE
|
|
336
|
+
/* document.source(selector) → raw YAML text of the node at selector */
|
|
337
|
+
static VALUE document_source(VALUE self, VALUE selector) {
|
|
318
338
|
struct Document *document = get_document(self);
|
|
319
|
-
char *text = yerba_document_source(document, StringValueCStr(
|
|
339
|
+
char *text = yerba_document_source(document, StringValueCStr(selector));
|
|
320
340
|
|
|
321
341
|
if (!text) return Qnil;
|
|
322
342
|
|
|
@@ -326,17 +346,22 @@ static VALUE document_source(VALUE self, VALUE path) {
|
|
|
326
346
|
return result;
|
|
327
347
|
}
|
|
328
348
|
|
|
329
|
-
/* document.get_value(
|
|
330
|
-
static VALUE document_get_value(VALUE self, VALUE
|
|
349
|
+
/* document.get_value(selector) → parsed Ruby object (Hash/Array/String/Integer/etc) */
|
|
350
|
+
static VALUE document_get_value(VALUE self, VALUE selector) {
|
|
331
351
|
struct Document *document = get_document(self);
|
|
332
|
-
char *json = yerba_document_get_value(document, StringValueCStr(
|
|
352
|
+
char *json = yerba_document_get_value(document, StringValueCStr(selector));
|
|
333
353
|
|
|
334
354
|
if (!json) return Qnil;
|
|
335
355
|
|
|
336
356
|
VALUE json_string = make_utf8_string(json);
|
|
337
357
|
yerba_string_free(json);
|
|
338
358
|
|
|
339
|
-
|
|
359
|
+
VALUE options = rb_hash_new();
|
|
360
|
+
rb_hash_aset(options, ID2SYM(rb_intern("allow_nan")), Qtrue);
|
|
361
|
+
|
|
362
|
+
VALUE arguments[] = {json_string, options};
|
|
363
|
+
|
|
364
|
+
return rb_funcallv_kw(rb_path2class("JSON"), rb_intern("parse"), 2, arguments, RB_PASS_KEYWORDS);
|
|
340
365
|
}
|
|
341
366
|
|
|
342
367
|
/* document.values → the whole document as Ruby objects, cached until the document changes */
|
|
@@ -356,6 +381,44 @@ static VALUE document_values(VALUE self) {
|
|
|
356
381
|
return values;
|
|
357
382
|
}
|
|
358
383
|
|
|
384
|
+
/* document.native_node_records → [[parent, type, selector, key, value, has_value, location, key_location], ...] */
|
|
385
|
+
static VALUE document_node_records(VALUE self) {
|
|
386
|
+
YerbaNodeList list = yerba_document_nodes(get_document(self));
|
|
387
|
+
VALUE records = rb_ary_new_capa((long)list.length);
|
|
388
|
+
|
|
389
|
+
for (size_t i = 0; i < list.length; i++) {
|
|
390
|
+
YerbaNodeRecord record = list.records[i];
|
|
391
|
+
VALUE type;
|
|
392
|
+
|
|
393
|
+
switch (record.node_type) {
|
|
394
|
+
case NODE_TYPE_SCALAR: type = ID2SYM(rb_intern("scalar")); break;
|
|
395
|
+
case NODE_TYPE_MAP: type = ID2SYM(rb_intern("map")); break;
|
|
396
|
+
case NODE_TYPE_SEQUENCE: type = ID2SYM(rb_intern("sequence")); break;
|
|
397
|
+
default: type = Qnil; break;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
rb_ary_push(records, rb_ary_new_from_args(8,
|
|
401
|
+
LONG2NUM(record.parent),
|
|
402
|
+
type,
|
|
403
|
+
make_utf8_string(record.selector),
|
|
404
|
+
record.key_name ? make_utf8_string(record.key_name) : Qnil,
|
|
405
|
+
typed_value_to_ruby(record.value),
|
|
406
|
+
record.has_value ? Qtrue : Qfalse,
|
|
407
|
+
location_to_ruby(record.location),
|
|
408
|
+
record.key_name ? location_to_ruby(record.key_location) : Qnil
|
|
409
|
+
));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
yerba_node_list_free(list);
|
|
413
|
+
|
|
414
|
+
return records;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/* document.native_generation → changes whenever the document is edited */
|
|
418
|
+
static VALUE document_generation(VALUE self) {
|
|
419
|
+
return ULL2NUM(yerba_document_generation(get_document(self)));
|
|
420
|
+
}
|
|
421
|
+
|
|
359
422
|
/* document.selectors → ["database", "database.host", "tags", "tags[]", ...] */
|
|
360
423
|
static VALUE document_selectors(VALUE self) {
|
|
361
424
|
struct Document *document = get_document(self);
|
|
@@ -370,9 +433,9 @@ static VALUE document_selectors(VALUE self) {
|
|
|
370
433
|
}
|
|
371
434
|
|
|
372
435
|
/* document.keys_at(selector) → ["host", "port", ...] */
|
|
373
|
-
static VALUE document_keys_at(VALUE self, VALUE
|
|
436
|
+
static VALUE document_keys_at(VALUE self, VALUE selector) {
|
|
374
437
|
struct Document *document = get_document(self);
|
|
375
|
-
char *json = yerba_document_keys(document, StringValueCStr(
|
|
438
|
+
char *json = yerba_document_keys(document, StringValueCStr(selector));
|
|
376
439
|
|
|
377
440
|
if (!json) return rb_ary_new();
|
|
378
441
|
|
|
@@ -383,9 +446,9 @@ static VALUE document_keys_at(VALUE self, VALUE path) {
|
|
|
383
446
|
}
|
|
384
447
|
|
|
385
448
|
/* document.locations(selector) → [Yerba::Location, ...] */
|
|
386
|
-
static VALUE document_locations(VALUE self, VALUE
|
|
449
|
+
static VALUE document_locations(VALUE self, VALUE selector) {
|
|
387
450
|
struct Document *document = get_document(self);
|
|
388
|
-
char *json = yerba_document_resolve_selectors(document, StringValueCStr(
|
|
451
|
+
char *json = yerba_document_resolve_selectors(document, StringValueCStr(selector));
|
|
389
452
|
|
|
390
453
|
if (!json) return rb_ary_new();
|
|
391
454
|
|
|
@@ -397,8 +460,8 @@ static VALUE document_locations(VALUE self, VALUE path) {
|
|
|
397
460
|
VALUE array = rb_ary_new_capa(length);
|
|
398
461
|
|
|
399
462
|
for (long i = 0; i < length; i++) {
|
|
400
|
-
VALUE
|
|
401
|
-
YerbaGetResult result = yerba_document_get(document, StringValueCStr(
|
|
463
|
+
VALUE concrete_selector = rb_ary_entry(resolved, i);
|
|
464
|
+
YerbaGetResult result = yerba_document_get(document, StringValueCStr(concrete_selector));
|
|
402
465
|
|
|
403
466
|
if (result.error) {
|
|
404
467
|
yerba_get_result_free(result);
|
|
@@ -418,10 +481,10 @@ static VALUE document_locations(VALUE self, VALUE path) {
|
|
|
418
481
|
return array;
|
|
419
482
|
}
|
|
420
483
|
|
|
421
|
-
/* document.resolve_selectors(
|
|
422
|
-
static VALUE document_resolve_selectors(VALUE self, VALUE
|
|
484
|
+
/* document.resolve_selectors(selector) → ["[0].speakers[0]", "[0].speakers[1]", ...] */
|
|
485
|
+
static VALUE document_resolve_selectors(VALUE self, VALUE selector) {
|
|
423
486
|
struct Document *document = get_document(self);
|
|
424
|
-
char *json = yerba_document_resolve_selectors(document, StringValueCStr(
|
|
487
|
+
char *json = yerba_document_resolve_selectors(document, StringValueCStr(selector));
|
|
425
488
|
|
|
426
489
|
if (!json) return rb_ary_new();
|
|
427
490
|
|
|
@@ -456,10 +519,10 @@ static VALUE yerba_s_quote_scalar(int argc, VALUE *argv, VALUE self) {
|
|
|
456
519
|
return result;
|
|
457
520
|
}
|
|
458
521
|
|
|
459
|
-
/* document.get_quote_style(
|
|
460
|
-
static VALUE document_get_quote_style(VALUE self, VALUE
|
|
522
|
+
/* document.get_quote_style(selector) → :plain, :single, :double, :literal, etc. or nil */
|
|
523
|
+
static VALUE document_get_quote_style(VALUE self, VALUE selector) {
|
|
461
524
|
struct Document *document = get_document(self);
|
|
462
|
-
char *style = yerba_document_get_quote_style(document, StringValueCStr(
|
|
525
|
+
char *style = yerba_document_get_quote_style(document, StringValueCStr(selector));
|
|
463
526
|
|
|
464
527
|
if (style == NULL) return Qnil;
|
|
465
528
|
|
|
@@ -470,8 +533,8 @@ static VALUE document_get_quote_style(VALUE self, VALUE path) {
|
|
|
470
533
|
return symbol;
|
|
471
534
|
}
|
|
472
535
|
|
|
473
|
-
/* document.set_quote_style(
|
|
474
|
-
static VALUE document_set_quote_style(VALUE self, VALUE
|
|
536
|
+
/* document.set_quote_style(selector, style) */
|
|
537
|
+
static VALUE document_set_quote_style(VALUE self, VALUE selector, VALUE style) {
|
|
475
538
|
struct Document *document = get_document(self);
|
|
476
539
|
|
|
477
540
|
const char *style_string;
|
|
@@ -484,17 +547,17 @@ static VALUE document_set_quote_style(VALUE self, VALUE path, VALUE style) {
|
|
|
484
547
|
rb_raise(rb_eError, "Invalid quote style (expected Symbol or String)");
|
|
485
548
|
}
|
|
486
549
|
|
|
487
|
-
YerbaResult result = yerba_document_set_quote_style(document, StringValueCStr(
|
|
550
|
+
YerbaResult result = yerba_document_set_quote_style(document, StringValueCStr(selector), style_string);
|
|
488
551
|
|
|
489
552
|
check_result(result);
|
|
490
553
|
|
|
491
554
|
return self;
|
|
492
555
|
}
|
|
493
556
|
|
|
494
|
-
/* document.get_collection_style(
|
|
495
|
-
static VALUE document_get_collection_style(VALUE self, VALUE
|
|
557
|
+
/* document.get_collection_style(selector) → :flow, :block, or nil */
|
|
558
|
+
static VALUE document_get_collection_style(VALUE self, VALUE selector) {
|
|
496
559
|
struct Document *document = get_document(self);
|
|
497
|
-
char *style = yerba_document_get_collection_style(document, StringValueCStr(
|
|
560
|
+
char *style = yerba_document_get_collection_style(document, StringValueCStr(selector));
|
|
498
561
|
|
|
499
562
|
if (style == NULL) return Qnil;
|
|
500
563
|
|
|
@@ -505,8 +568,8 @@ static VALUE document_get_collection_style(VALUE self, VALUE path) {
|
|
|
505
568
|
return symbol;
|
|
506
569
|
}
|
|
507
570
|
|
|
508
|
-
/* document.set_collection_style(
|
|
509
|
-
static VALUE document_set_collection_style(VALUE self, VALUE
|
|
571
|
+
/* document.set_collection_style(selector, style) */
|
|
572
|
+
static VALUE document_set_collection_style(VALUE self, VALUE selector, VALUE style) {
|
|
510
573
|
struct Document *document = get_document(self);
|
|
511
574
|
|
|
512
575
|
const char *style_string;
|
|
@@ -519,17 +582,17 @@ static VALUE document_set_collection_style(VALUE self, VALUE path, VALUE style)
|
|
|
519
582
|
rb_raise(rb_eError, "Invalid collection style (expected Symbol or String)");
|
|
520
583
|
}
|
|
521
584
|
|
|
522
|
-
YerbaResult result = yerba_document_set_collection_style(document, StringValueCStr(
|
|
585
|
+
YerbaResult result = yerba_document_set_collection_style(document, StringValueCStr(selector), style_string);
|
|
523
586
|
|
|
524
587
|
check_result(result);
|
|
525
588
|
|
|
526
589
|
return self;
|
|
527
590
|
}
|
|
528
591
|
|
|
529
|
-
/* document.get_sequence_indent(
|
|
530
|
-
static VALUE document_get_sequence_indent(VALUE self, VALUE
|
|
592
|
+
/* document.get_sequence_indent(selector) → :compact, :indented, or nil */
|
|
593
|
+
static VALUE document_get_sequence_indent(VALUE self, VALUE selector) {
|
|
531
594
|
struct Document *document = get_document(self);
|
|
532
|
-
char *style = yerba_document_get_sequence_indent(document, StringValueCStr(
|
|
595
|
+
char *style = yerba_document_get_sequence_indent(document, StringValueCStr(selector));
|
|
533
596
|
|
|
534
597
|
if (style == NULL) return Qnil;
|
|
535
598
|
|
|
@@ -540,8 +603,8 @@ static VALUE document_get_sequence_indent(VALUE self, VALUE path) {
|
|
|
540
603
|
return symbol;
|
|
541
604
|
}
|
|
542
605
|
|
|
543
|
-
/* document.set_sequence_indent(
|
|
544
|
-
static VALUE document_set_sequence_indent(VALUE self, VALUE
|
|
606
|
+
/* document.set_sequence_indent(selector, style) */
|
|
607
|
+
static VALUE document_set_sequence_indent(VALUE self, VALUE selector, VALUE style) {
|
|
545
608
|
struct Document *document = get_document(self);
|
|
546
609
|
|
|
547
610
|
const char *style_string;
|
|
@@ -554,38 +617,51 @@ static VALUE document_set_sequence_indent(VALUE self, VALUE path, VALUE style) {
|
|
|
554
617
|
rb_raise(rb_eError, "Invalid sequence indent style (expected Symbol or String)");
|
|
555
618
|
}
|
|
556
619
|
|
|
557
|
-
YerbaResult result = yerba_document_set_sequence_indent(document, StringValueCStr(
|
|
620
|
+
YerbaResult result = yerba_document_set_sequence_indent(document, StringValueCStr(selector), style_string);
|
|
558
621
|
|
|
559
622
|
check_result(result);
|
|
560
623
|
|
|
561
624
|
return self;
|
|
562
625
|
}
|
|
563
626
|
|
|
564
|
-
/*
|
|
627
|
+
/* TODO(v1.0): stop reading the deprecated path: keyword. */
|
|
628
|
+
static VALUE selector_option(VALUE opts) {
|
|
629
|
+
VALUE selector = rb_hash_aref(opts, ID2SYM(rb_intern("selector")));
|
|
630
|
+
|
|
631
|
+
if (!NIL_P(selector)) return selector;
|
|
632
|
+
|
|
633
|
+
VALUE path = rb_hash_aref(opts, ID2SYM(rb_intern("path")));
|
|
634
|
+
|
|
635
|
+
if (!NIL_P(path)) rb_warn("Yerba: the path: keyword is deprecated, use selector: instead");
|
|
636
|
+
|
|
637
|
+
return path;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/* document.condition?(condition, selector: "") */
|
|
565
641
|
static VALUE document_condition_p(int argc, VALUE *argv, VALUE self) {
|
|
566
642
|
VALUE condition, opts;
|
|
567
643
|
rb_scan_args(argc, argv, "1:", &condition, &opts);
|
|
568
644
|
|
|
569
|
-
const char *
|
|
645
|
+
const char *parent_selector = "";
|
|
570
646
|
if (!NIL_P(opts)) {
|
|
571
|
-
VALUE
|
|
647
|
+
VALUE v_selector = selector_option(opts);
|
|
572
648
|
|
|
573
|
-
if (!NIL_P(
|
|
574
|
-
|
|
649
|
+
if (!NIL_P(v_selector)) {
|
|
650
|
+
parent_selector = StringValueCStr(v_selector);
|
|
575
651
|
}
|
|
576
652
|
}
|
|
577
653
|
|
|
578
654
|
struct Document *document = get_document(self);
|
|
579
655
|
|
|
580
|
-
check_condition(StringValueCStr(condition),
|
|
656
|
+
check_condition(StringValueCStr(condition), parent_selector[0] != '\0');
|
|
581
657
|
|
|
582
|
-
return yerba_document_evaluate_condition(document,
|
|
658
|
+
return yerba_document_evaluate_condition(document, parent_selector, StringValueCStr(condition)) ? Qtrue : Qfalse;
|
|
583
659
|
}
|
|
584
660
|
|
|
585
|
-
/* document.find(
|
|
661
|
+
/* document.find(selector, condition: nil, select: nil) */
|
|
586
662
|
static VALUE document_find(int argc, VALUE *argv, VALUE self) {
|
|
587
|
-
VALUE
|
|
588
|
-
rb_scan_args(argc, argv, "1:", &
|
|
663
|
+
VALUE selector, opts;
|
|
664
|
+
rb_scan_args(argc, argv, "1:", &selector, &opts);
|
|
589
665
|
|
|
590
666
|
const char *condition = NULL;
|
|
591
667
|
const char *select = NULL;
|
|
@@ -602,7 +678,7 @@ static VALUE document_find(int argc, VALUE *argv, VALUE self) {
|
|
|
602
678
|
|
|
603
679
|
check_condition(condition, true);
|
|
604
680
|
|
|
605
|
-
char *json = yerba_document_find(document, StringValueCStr(
|
|
681
|
+
char *json = yerba_document_find(document, StringValueCStr(selector), condition, select);
|
|
606
682
|
|
|
607
683
|
if (!json) return rb_ary_new();
|
|
608
684
|
|
|
@@ -655,10 +731,10 @@ static struct TypedValue ruby_to_typed_value(VALUE value, char *number_buffer) {
|
|
|
655
731
|
return result;
|
|
656
732
|
}
|
|
657
733
|
|
|
658
|
-
/* document.set(
|
|
734
|
+
/* document.set(selector, value, condition: nil, if_exists: false, if_missing: false, plain: false, all: false) */
|
|
659
735
|
static VALUE document_set(int argc, VALUE *argv, VALUE self) {
|
|
660
|
-
VALUE
|
|
661
|
-
rb_scan_args(argc, argv, "2:", &
|
|
736
|
+
VALUE selector, value, opts;
|
|
737
|
+
rb_scan_args(argc, argv, "2:", &selector, &value, &opts);
|
|
662
738
|
|
|
663
739
|
struct Document *document = get_document(self);
|
|
664
740
|
|
|
@@ -668,8 +744,19 @@ static VALUE document_set(int argc, VALUE *argv, VALUE self) {
|
|
|
668
744
|
VALUE v_if_exists = rb_hash_aref(opts, ID2SYM(rb_intern("if_exists")));
|
|
669
745
|
VALUE v_if_missing = rb_hash_aref(opts, ID2SYM(rb_intern("if_missing")));
|
|
670
746
|
|
|
671
|
-
if (RTEST(v_if_exists) && !yerba_document_exists(document, StringValueCStr(
|
|
672
|
-
|
|
747
|
+
if (RTEST(v_if_exists) && !yerba_document_exists(document, StringValueCStr(selector))) return self;
|
|
748
|
+
|
|
749
|
+
if (RTEST(v_if_missing)) {
|
|
750
|
+
if (yerba_document_exists(document, StringValueCStr(selector))) return self;
|
|
751
|
+
|
|
752
|
+
VALUE insert_opts = rb_hash_new();
|
|
753
|
+
rb_hash_aset(insert_opts, ID2SYM(rb_intern("plain")), rb_hash_aref(opts, ID2SYM(rb_intern("plain"))));
|
|
754
|
+
|
|
755
|
+
VALUE insert_argv[3] = { selector, value, insert_opts };
|
|
756
|
+
rb_funcallv_kw(self, rb_intern("insert"), 3, insert_argv, RB_PASS_KEYWORDS);
|
|
757
|
+
|
|
758
|
+
return self;
|
|
759
|
+
}
|
|
673
760
|
}
|
|
674
761
|
|
|
675
762
|
char number_buffer[64];
|
|
@@ -685,16 +772,16 @@ static VALUE document_set(int argc, VALUE *argv, VALUE self) {
|
|
|
685
772
|
if (RTEST(v_plain)) plain = true;
|
|
686
773
|
}
|
|
687
774
|
|
|
688
|
-
YerbaResult result = yerba_document_set(document, StringValueCStr(
|
|
775
|
+
YerbaResult result = yerba_document_set(document, StringValueCStr(selector), typed_value.text, typed_value.length, typed_value.type, plain, all);
|
|
689
776
|
check_result(result);
|
|
690
777
|
|
|
691
778
|
return self;
|
|
692
779
|
}
|
|
693
780
|
|
|
694
|
-
/* document.insert(
|
|
781
|
+
/* document.insert(selector, value, before: nil, after: nil, at: nil, plain: false, style: nil) */
|
|
695
782
|
static VALUE document_insert(int argc, VALUE *argv, VALUE self) {
|
|
696
|
-
VALUE
|
|
697
|
-
rb_scan_args(argc, argv, "2:", &
|
|
783
|
+
VALUE selector, value, opts;
|
|
784
|
+
rb_scan_args(argc, argv, "2:", &selector, &value, &opts);
|
|
698
785
|
|
|
699
786
|
const char *before = NULL;
|
|
700
787
|
const char *after = NULL;
|
|
@@ -725,17 +812,17 @@ static VALUE document_insert(int argc, VALUE *argv, VALUE self) {
|
|
|
725
812
|
|
|
726
813
|
struct Document *document = get_document(self);
|
|
727
814
|
YerbaResult result =
|
|
728
|
-
yerba_document_insert(document, StringValueCStr(
|
|
815
|
+
yerba_document_insert(document, StringValueCStr(selector), typed_value.text, typed_value.length, typed_value.type, plain, style,
|
|
729
816
|
before, after, at);
|
|
730
817
|
check_result(result);
|
|
731
818
|
|
|
732
819
|
return self;
|
|
733
820
|
}
|
|
734
821
|
|
|
735
|
-
/* document.insert_object(
|
|
822
|
+
/* document.insert_object(selector, object, before: nil, after: nil, at: nil) */
|
|
736
823
|
static VALUE document_insert_object(int argc, VALUE *argv, VALUE self) {
|
|
737
|
-
VALUE
|
|
738
|
-
rb_scan_args(argc, argv, "2:", &
|
|
824
|
+
VALUE selector, object, opts;
|
|
825
|
+
rb_scan_args(argc, argv, "2:", &selector, &object, &opts);
|
|
739
826
|
|
|
740
827
|
const char *before = NULL;
|
|
741
828
|
const char *after = NULL;
|
|
@@ -754,51 +841,51 @@ static VALUE document_insert_object(int argc, VALUE *argv, VALUE self) {
|
|
|
754
841
|
struct Document *document = get_document(self);
|
|
755
842
|
VALUE json_string = rb_funcall(rb_path2class("JSON"), rb_intern("generate"), 1, object);
|
|
756
843
|
|
|
757
|
-
YerbaResult result = yerba_document_insert_object(document, StringValueCStr(
|
|
844
|
+
YerbaResult result = yerba_document_insert_object(document, StringValueCStr(selector), StringValueCStr(json_string), before, after, at);
|
|
758
845
|
check_result(result);
|
|
759
846
|
return self;
|
|
760
847
|
}
|
|
761
848
|
|
|
762
|
-
/* document.insert_objects(
|
|
763
|
-
static VALUE document_insert_objects(VALUE self, VALUE
|
|
849
|
+
/* document.insert_objects(selector, array) */
|
|
850
|
+
static VALUE document_insert_objects(VALUE self, VALUE selector, VALUE array) {
|
|
764
851
|
struct Document *document = get_document(self);
|
|
765
852
|
VALUE json_string = rb_funcall(rb_path2class("JSON"), rb_intern("generate"), 1, array);
|
|
766
853
|
|
|
767
|
-
YerbaResult result = yerba_document_insert_objects(document, StringValueCStr(
|
|
854
|
+
YerbaResult result = yerba_document_insert_objects(document, StringValueCStr(selector), StringValueCStr(json_string));
|
|
768
855
|
check_result(result);
|
|
769
856
|
|
|
770
857
|
return self;
|
|
771
858
|
}
|
|
772
859
|
|
|
773
|
-
/* document.delete(
|
|
860
|
+
/* document.delete(selector, condition: nil) */
|
|
774
861
|
static VALUE document_delete(int argc, VALUE *argv, VALUE self) {
|
|
775
|
-
VALUE
|
|
776
|
-
rb_scan_args(argc, argv, "1:", &
|
|
862
|
+
VALUE selector, opts;
|
|
863
|
+
rb_scan_args(argc, argv, "1:", &selector, &opts);
|
|
777
864
|
|
|
778
865
|
struct Document *document = get_document(self);
|
|
779
866
|
if (!should_proceed(document, opts)) return self;
|
|
780
867
|
|
|
781
|
-
YerbaResult result = yerba_document_delete(document, StringValueCStr(
|
|
868
|
+
YerbaResult result = yerba_document_delete(document, StringValueCStr(selector));
|
|
782
869
|
|
|
783
870
|
check_result(result);
|
|
784
871
|
|
|
785
872
|
return self;
|
|
786
873
|
}
|
|
787
874
|
|
|
788
|
-
/* document.remove(
|
|
789
|
-
static VALUE document_remove(VALUE self, VALUE
|
|
875
|
+
/* document.remove(selector, value) */
|
|
876
|
+
static VALUE document_remove(VALUE self, VALUE selector, VALUE value) {
|
|
790
877
|
struct Document *document = get_document(self);
|
|
791
|
-
YerbaResult result = yerba_document_remove(document, StringValueCStr(
|
|
878
|
+
YerbaResult result = yerba_document_remove(document, StringValueCStr(selector), StringValueCStr(value));
|
|
792
879
|
|
|
793
880
|
check_result(result);
|
|
794
881
|
|
|
795
882
|
return self;
|
|
796
883
|
}
|
|
797
884
|
|
|
798
|
-
/* document.remove_at(
|
|
799
|
-
static VALUE document_remove_at(VALUE self, VALUE
|
|
885
|
+
/* document.remove_at(selector, index) */
|
|
886
|
+
static VALUE document_remove_at(VALUE self, VALUE selector, VALUE index) {
|
|
800
887
|
struct Document *document = get_document(self);
|
|
801
|
-
YerbaResult result = yerba_document_remove_at(document, StringValueCStr(
|
|
888
|
+
YerbaResult result = yerba_document_remove_at(document, StringValueCStr(selector), NUM2SIZET(index));
|
|
802
889
|
|
|
803
890
|
check_result(result);
|
|
804
891
|
|
|
@@ -815,27 +902,46 @@ static VALUE document_rename(VALUE self, VALUE source, VALUE destination) {
|
|
|
815
902
|
return self;
|
|
816
903
|
}
|
|
817
904
|
|
|
818
|
-
/* document.sort(
|
|
905
|
+
/* document.sort(selector = "", by: nil, order: nil, case_sensitive: false)
|
|
906
|
+
*
|
|
907
|
+
* by: a field, several fields separated by commas or spaces, or an Array of fields
|
|
908
|
+
* order: :asc, :desc, or an explicit order of values (Array or comma-separated String)
|
|
909
|
+
*/
|
|
819
910
|
static VALUE document_sort(int argc, VALUE *argv, VALUE self) {
|
|
820
|
-
VALUE
|
|
821
|
-
rb_scan_args(argc, argv, "01:", &
|
|
911
|
+
VALUE selector, opts;
|
|
912
|
+
rb_scan_args(argc, argv, "01:", &selector, &opts);
|
|
822
913
|
|
|
823
|
-
if (NIL_P(
|
|
914
|
+
if (NIL_P(selector)) selector = rb_str_new_cstr("");
|
|
824
915
|
|
|
825
|
-
|
|
916
|
+
VALUE by_value = Qnil;
|
|
917
|
+
VALUE order_csv = Qnil;
|
|
918
|
+
bool descending = false;
|
|
826
919
|
bool case_sensitive = false;
|
|
827
|
-
VALUE v_order = Qnil;
|
|
828
920
|
|
|
829
921
|
if (!NIL_P(opts)) {
|
|
830
922
|
VALUE v_by = rb_hash_aref(opts, ID2SYM(rb_intern("by")));
|
|
831
|
-
v_order = rb_hash_aref(opts, ID2SYM(rb_intern("order")));
|
|
923
|
+
VALUE v_order = rb_hash_aref(opts, ID2SYM(rb_intern("order")));
|
|
832
924
|
VALUE v_case_sensitive = rb_hash_aref(opts, ID2SYM(rb_intern("case_sensitive")));
|
|
833
925
|
|
|
834
|
-
if (
|
|
835
|
-
|
|
836
|
-
|
|
926
|
+
if (RB_TYPE_P(v_by, T_ARRAY)) {
|
|
927
|
+
by_value = rb_ary_join(v_by, rb_str_new_cstr(","));
|
|
928
|
+
} else if (SYMBOL_P(v_by)) {
|
|
929
|
+
by_value = rb_sym2str(v_by);
|
|
837
930
|
} else if (!NIL_P(v_by)) {
|
|
838
|
-
|
|
931
|
+
by_value = rb_obj_as_string(v_by);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
if (RB_TYPE_P(v_order, T_ARRAY)) {
|
|
935
|
+
order_csv = rb_ary_join(v_order, rb_str_new_cstr(","));
|
|
936
|
+
} else if (!NIL_P(v_order)) {
|
|
937
|
+
VALUE order_string = SYMBOL_P(v_order) ? rb_sym2str(v_order) : rb_obj_as_string(v_order);
|
|
938
|
+
const char *order = StringValueCStr(order_string);
|
|
939
|
+
|
|
940
|
+
if (strcmp(order, "desc") == 0 || strcmp(order, "descending") == 0) {
|
|
941
|
+
descending = true;
|
|
942
|
+
} else if (strcmp(order, "asc") != 0 && strcmp(order, "ascending") != 0) {
|
|
943
|
+
order_csv = order_string;
|
|
944
|
+
}
|
|
839
945
|
}
|
|
840
946
|
|
|
841
947
|
if (RTEST(v_case_sensitive)) {
|
|
@@ -844,62 +950,37 @@ static VALUE document_sort(int argc, VALUE *argv, VALUE self) {
|
|
|
844
950
|
}
|
|
845
951
|
|
|
846
952
|
struct Document *document = get_document(self);
|
|
847
|
-
const char *path_string = StringValueCStr(
|
|
848
|
-
|
|
849
|
-
if (RB_TYPE_P(v_order, T_ARRAY)) {
|
|
850
|
-
VALUE order_csv = rb_ary_join(v_order, rb_str_new_cstr(","));
|
|
851
|
-
const char *order_string = StringValueCStr(order_csv);
|
|
852
|
-
const char *reorder_path = StringValueCStr(path);
|
|
853
|
-
const char *reorder_by;
|
|
854
|
-
|
|
855
|
-
if (by) {
|
|
856
|
-
VALUE reorder_by_value = rb_hash_aref(opts, ID2SYM(rb_intern("by")));
|
|
857
|
-
|
|
858
|
-
if (SYMBOL_P(reorder_by_value)) {
|
|
859
|
-
reorder_by_value = rb_sym2str(reorder_by_value);
|
|
860
|
-
}
|
|
953
|
+
const char *path_string = StringValueCStr(selector);
|
|
954
|
+
const char *by = NIL_P(by_value) ? NULL : StringValueCStr(by_value);
|
|
861
955
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
reorder_by = ".";
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
YerbaResult result = yerba_document_reorder(document, reorder_path, reorder_by, order_string);
|
|
956
|
+
if (!NIL_P(order_csv)) {
|
|
957
|
+
YerbaResult result = yerba_document_reorder(document, path_string, by ? by : ".", StringValueCStr(order_csv));
|
|
868
958
|
check_result(result);
|
|
869
959
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
const char *order = NULL;
|
|
960
|
+
RB_GC_GUARD(by_value);
|
|
961
|
+
RB_GC_GUARD(order_csv);
|
|
874
962
|
|
|
875
|
-
|
|
876
|
-
VALUE order_string = rb_sym2str(v_order);
|
|
877
|
-
order = StringValueCStr(order_string);
|
|
878
|
-
} else if (!NIL_P(v_order)) {
|
|
879
|
-
order = StringValueCStr(v_order);
|
|
963
|
+
return self;
|
|
880
964
|
}
|
|
881
965
|
|
|
882
966
|
VALUE by_with_order = Qnil;
|
|
883
967
|
|
|
884
|
-
if (
|
|
885
|
-
|
|
886
|
-
by_with_order = rb_sprintf("%s:desc", by);
|
|
887
|
-
} else {
|
|
888
|
-
by_with_order = rb_str_new_cstr(":desc");
|
|
889
|
-
}
|
|
890
|
-
|
|
968
|
+
if (descending) {
|
|
969
|
+
by_with_order = by ? rb_sprintf("%s:desc", by) : rb_str_new_cstr(":desc");
|
|
891
970
|
by = StringValueCStr(by_with_order);
|
|
892
971
|
}
|
|
893
972
|
|
|
894
973
|
YerbaResult result = yerba_document_sort(document, path_string, by, case_sensitive);
|
|
895
|
-
|
|
896
974
|
check_result(result);
|
|
897
975
|
|
|
976
|
+
RB_GC_GUARD(by_value);
|
|
977
|
+
RB_GC_GUARD(by_with_order);
|
|
978
|
+
|
|
898
979
|
return self;
|
|
899
980
|
}
|
|
900
981
|
|
|
901
|
-
/* document.sort_keys(
|
|
902
|
-
static VALUE document_sort_keys(VALUE self, VALUE
|
|
982
|
+
/* document.sort_keys(selector, order) */
|
|
983
|
+
static VALUE document_sort_keys(VALUE self, VALUE selector, VALUE order) {
|
|
903
984
|
struct Document *document = get_document(self);
|
|
904
985
|
|
|
905
986
|
VALUE order_string;
|
|
@@ -909,44 +990,44 @@ static VALUE document_sort_keys(VALUE self, VALUE path, VALUE order) {
|
|
|
909
990
|
order_string = order;
|
|
910
991
|
}
|
|
911
992
|
|
|
912
|
-
YerbaResult result = yerba_document_sort_keys(document, StringValueCStr(
|
|
993
|
+
YerbaResult result = yerba_document_sort_keys(document, StringValueCStr(selector), StringValueCStr(order_string));
|
|
913
994
|
|
|
914
995
|
check_result(result);
|
|
915
996
|
|
|
916
997
|
return self;
|
|
917
998
|
}
|
|
918
999
|
|
|
919
|
-
/* document.quote_style(
|
|
1000
|
+
/* document.quote_style(selector: nil, key_style: nil, value_style: nil) */
|
|
920
1001
|
static VALUE document_quote_style(int argc, VALUE *argv, VALUE self) {
|
|
921
1002
|
VALUE opts;
|
|
922
1003
|
rb_scan_args(argc, argv, ":", &opts);
|
|
923
1004
|
|
|
924
|
-
const char *
|
|
1005
|
+
const char *selector = NULL;
|
|
925
1006
|
const char *key_style = NULL;
|
|
926
1007
|
const char *value_style = NULL;
|
|
927
1008
|
|
|
928
1009
|
if (!NIL_P(opts)) {
|
|
929
|
-
VALUE
|
|
1010
|
+
VALUE v_selector = selector_option(opts);
|
|
930
1011
|
VALUE v_key_style = rb_hash_aref(opts, ID2SYM(rb_intern("key_style")));
|
|
931
1012
|
VALUE v_value_style = rb_hash_aref(opts, ID2SYM(rb_intern("value_style")));
|
|
932
1013
|
|
|
933
|
-
if (!NIL_P(
|
|
1014
|
+
if (!NIL_P(v_selector)) selector = StringValueCStr(v_selector);
|
|
934
1015
|
if (!NIL_P(v_key_style)) key_style = StringValueCStr(v_key_style);
|
|
935
1016
|
if (!NIL_P(v_value_style)) value_style = StringValueCStr(v_value_style);
|
|
936
1017
|
}
|
|
937
1018
|
|
|
938
1019
|
struct Document *document = get_document(self);
|
|
939
|
-
YerbaResult result = yerba_document_quote_style(document,
|
|
1020
|
+
YerbaResult result = yerba_document_quote_style(document, selector, key_style, value_style);
|
|
940
1021
|
|
|
941
1022
|
check_result(result);
|
|
942
1023
|
|
|
943
1024
|
return self;
|
|
944
1025
|
}
|
|
945
1026
|
|
|
946
|
-
/* document.blank_lines(
|
|
947
|
-
static VALUE document_blank_lines(VALUE self, VALUE
|
|
1027
|
+
/* document.blank_lines(selector, count) */
|
|
1028
|
+
static VALUE document_blank_lines(VALUE self, VALUE selector, VALUE count) {
|
|
948
1029
|
struct Document *document = get_document(self);
|
|
949
|
-
YerbaResult result = yerba_document_blank_lines(document, StringValueCStr(
|
|
1030
|
+
YerbaResult result = yerba_document_blank_lines(document, StringValueCStr(selector), NUM2SIZET(count));
|
|
950
1031
|
|
|
951
1032
|
check_result(result);
|
|
952
1033
|
|
|
@@ -1027,20 +1108,20 @@ static VALUE document_changed_p(VALUE self) {
|
|
|
1027
1108
|
|
|
1028
1109
|
/* document.location(selector = nil) → Yerba::Location */
|
|
1029
1110
|
static VALUE document_location(int argc, VALUE *argv, VALUE self) {
|
|
1030
|
-
VALUE
|
|
1031
|
-
rb_scan_args(argc, argv, "01", &
|
|
1111
|
+
VALUE selector;
|
|
1112
|
+
rb_scan_args(argc, argv, "01", &selector);
|
|
1032
1113
|
|
|
1033
1114
|
struct Document *document = get_document(self);
|
|
1034
|
-
const char *
|
|
1115
|
+
const char *selector_string = NIL_P(selector) ? "" : StringValueCStr(selector);
|
|
1035
1116
|
|
|
1036
|
-
YerbaGetResult result = yerba_document_get(document,
|
|
1117
|
+
YerbaGetResult result = yerba_document_get(document, selector_string);
|
|
1037
1118
|
|
|
1038
1119
|
if (result.error) {
|
|
1039
1120
|
yerba_get_result_free(result);
|
|
1040
1121
|
return Qnil;
|
|
1041
1122
|
}
|
|
1042
1123
|
|
|
1043
|
-
if (result.location.start_line == 0 && result.location.end_line == 0 && strlen(
|
|
1124
|
+
if (result.location.start_line == 0 && result.location.end_line == 0 && strlen(selector_string) > 0) {
|
|
1044
1125
|
yerba_get_result_free(result);
|
|
1045
1126
|
return Qnil;
|
|
1046
1127
|
}
|
|
@@ -1125,24 +1206,24 @@ static VALUE located_list_to_ruby(YerbaTypedList result, VALUE document) {
|
|
|
1125
1206
|
}
|
|
1126
1207
|
|
|
1127
1208
|
/* Collection.get(glob, selector) → [Yerba::Scalar|Map|Sequence, ...] */
|
|
1128
|
-
static VALUE collection_s_get(VALUE self, VALUE pattern, VALUE
|
|
1209
|
+
static VALUE collection_s_get(VALUE self, VALUE pattern, VALUE selector) {
|
|
1129
1210
|
(void) self;
|
|
1130
1211
|
|
|
1131
|
-
return located_list_to_ruby(yerba_glob_get(StringValueCStr(pattern), StringValueCStr(
|
|
1212
|
+
return located_list_to_ruby(yerba_glob_get(StringValueCStr(pattern), StringValueCStr(selector)), Qnil);
|
|
1132
1213
|
}
|
|
1133
1214
|
|
|
1134
1215
|
/* document.get_all(selector) → [Yerba::Scalar|Map|Sequence, ...] */
|
|
1135
|
-
static VALUE document_get_all(VALUE self, VALUE
|
|
1216
|
+
static VALUE document_get_all(VALUE self, VALUE selector) {
|
|
1136
1217
|
struct Document *document = get_document(self);
|
|
1137
1218
|
|
|
1138
|
-
return located_list_to_ruby(yerba_document_get_all(document, StringValueCStr(
|
|
1219
|
+
return located_list_to_ruby(yerba_document_get_all(document, StringValueCStr(selector)), self);
|
|
1139
1220
|
}
|
|
1140
1221
|
|
|
1141
|
-
/* Collection.find(glob,
|
|
1222
|
+
/* Collection.find(glob, selector, condition: nil, select: nil) */
|
|
1142
1223
|
static VALUE collection_s_find(int argc, VALUE *argv, VALUE self) {
|
|
1143
1224
|
(void)self;
|
|
1144
|
-
VALUE pattern,
|
|
1145
|
-
rb_scan_args(argc, argv, "2:", &pattern, &
|
|
1225
|
+
VALUE pattern, selector, opts;
|
|
1226
|
+
rb_scan_args(argc, argv, "2:", &pattern, &selector, &opts);
|
|
1146
1227
|
|
|
1147
1228
|
const char *condition = NULL;
|
|
1148
1229
|
const char *select = NULL;
|
|
@@ -1157,7 +1238,7 @@ static VALUE collection_s_find(int argc, VALUE *argv, VALUE self) {
|
|
|
1157
1238
|
|
|
1158
1239
|
check_condition(condition, true);
|
|
1159
1240
|
|
|
1160
|
-
YerbaTypedList result = yerba_glob_find(StringValueCStr(pattern), StringValueCStr(
|
|
1241
|
+
YerbaTypedList result = yerba_glob_find(StringValueCStr(pattern), StringValueCStr(selector), condition, select);
|
|
1161
1242
|
|
|
1162
1243
|
if (!result.json) return rb_ary_new();
|
|
1163
1244
|
|
|
@@ -1231,10 +1312,11 @@ void Init_yerba(void) {
|
|
|
1231
1312
|
rb_define_method(rb_cDocument, "initialize", document_initialize, -1);
|
|
1232
1313
|
rb_define_method(rb_cDocument, "replace_content!", document_replace_content, 1);
|
|
1233
1314
|
rb_define_singleton_method(rb_cDocument, "parse", document_s_parse, 1);
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
rb_define_method(rb_cDocument, "value_at", document_get_value, 1);
|
|
1315
|
+
rb_define_private_method(rb_cDocument, "native_node_at", document_bracket, 1);
|
|
1316
|
+
rb_define_private_method(rb_cDocument, "native_value_at", document_get_value, 1);
|
|
1237
1317
|
rb_define_method(rb_cDocument, "values", document_values, 0);
|
|
1318
|
+
rb_define_private_method(rb_cDocument, "native_node_records", document_node_records, 0);
|
|
1319
|
+
rb_define_private_method(rb_cDocument, "native_generation", document_generation, 0);
|
|
1238
1320
|
rb_define_method(rb_cDocument, "get_all", document_get_all, 1);
|
|
1239
1321
|
rb_define_method(rb_cDocument, "location", document_location, -1);
|
|
1240
1322
|
rb_define_method(rb_cDocument, "locations", document_locations, 1);
|