Module: Usamin

Defined in:
lib/usamin.rb,
lib/usamin/version.rb,
ext/usamin/usamin.cpp

Overview

When I was a child, I loved fairy tales. I wished for wonderland every time my mother read the tales to me. And now, I feel like I’m in the dream.

Defined Under Namespace

Classes: Array, Hash, ParserError, UsaminError, Value

Constant Summary collapse

VERSION =
"7.7.8"

Class Method Summary collapse

Class Method Details

.generate(obj) ⇒ String

Generate the JSON string from Ruby data structures.

Parameters:

  • obj (Object)

    an object to serialize

Returns:

  • (String)


1302
1303
1304
1305
1306
1307
# File 'ext/usamin/usamin.cpp', line 1302

static VALUE w_generate(const VALUE self, const VALUE value) {
    rapidjson::StringBuffer buf;
    rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
    write(writer, value);
    return new_utf8_str(buf.GetString(), buf.GetSize());
}

.load(source, opts = {}) ⇒ Object

Parse the JSON string into UsaminValue. If the document root is not an object or an array, the same value as #parse will be returned.

Parameters:

  • source (String)

    JSON string to parse

  • opts (::Hash) (defaults to: {})

    options

Options Hash (opts):

  • :fast (Object)

    fast mode (but not precise)

Returns:

  • (Object)


460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'ext/usamin/usamin.cpp', line 460

static VALUE w_load(const int argc, const VALUE *argv, const VALUE self) {
    VALUE source, options;
    rb_scan_args(argc, argv, "1:", &source, &options);
    RubynizedDocument *doc = new RubynizedDocument;
    auto result = parse(*doc, source, argc > 1 && RTEST(rb_hash_lookup(options, sym_fast)));
    if (!result) {
        delete doc;
        rb_raise(rb_eParserError, "%s Offset: %lu", GetParseError_En(result.Code()), result.Offset());
    }

    VALUE ret;
    switch (doc->GetType()) {
        case rapidjson::kObjectType:
            return make_hash(new UsaminValue(doc, true), true);
        case rapidjson::kArrayType:
            return make_array(new UsaminValue(doc, true), true);
        case rapidjson::kNullType:
            delete doc;
            return Qnil;
        case rapidjson::kFalseType:
            delete doc;
            return Qfalse;
        case rapidjson::kTrueType:
            delete doc;
            return Qtrue;
        case rapidjson::kNumberType:
            ret = eval_num(*doc);
            delete doc;
            return ret;
        case rapidjson::kStringType:
            ret = eval_str(*doc);
            delete doc;
            return ret;
        default:
            rb_raise(rb_eUsaminError, "Unknown Value Type: %d", doc->GetType());
            return Qnil;
    }
}

.parse(source, opts = {}) ⇒ Object

Parse the JSON string into Ruby data structures.

Parameters:

  • source (String)

    a JSON string to parse

  • opts (::Hash) (defaults to: {})

    options

Options Hash (opts):

  • :fast (Object)

    fast mode (but not precise)

Returns:

  • (Object)


508
509
510
511
512
513
514
515
516
# File 'ext/usamin/usamin.cpp', line 508

static VALUE w_parse(const int argc, const VALUE *argv, const VALUE self) {
    VALUE source, options;
    rb_scan_args(argc, argv, "1:", &source, &options);
    RubynizedDocument doc;
    auto result = parse(doc, source, argc > 1 && RTEST(rb_hash_lookup(options, sym_fast)));
    if (!result)
        rb_raise(rb_eParserError, "%s Offset: %lu", GetParseError_En(result.Code()), result.Offset());
    return eval_r(doc);
}

.pretty_generate(obj, opts = {}) ⇒ String

Generate the prettified JSON string from Ruby data structures.

Parameters:

  • obj (Object)

    an object to serialize

  • opts (::Hash) (defaults to: {})

    options

Options Hash (opts):

  • :indent (String) — default: ' '

    a string used to indent

  • :single_line_array (Boolean) — default: false

Returns:

  • (String)


1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
# File 'ext/usamin/usamin.cpp', line 1319

static VALUE w_pretty_generate(const int argc, const VALUE *argv, const VALUE self) {
    VALUE value, options;
    rb_scan_args(argc, argv, "1:", &value, &options);
    rapidjson::StringBuffer buf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);

    char indent_char = ' ';
    unsigned int indent_count = 2;
    if (argc > 1) {
        VALUE v_indent = rb_hash_lookup(options, sym_indent);
        if (RTEST(v_indent)) {
            if (RB_FIXNUM_P(v_indent)) {
                long l = FIX2LONG(v_indent);
                indent_count = l > 0 ? static_cast<unsigned int>(l) : 0;
            } else {
                long vlen = RSTRING_LEN(v_indent);
                if (vlen == 0) {
                    indent_count = 0;
                } else {
                    const char *indent_str = RSTRING_PTR(v_indent);
                    switch (indent_str[0]) {
                        case ' ':
                        case '\t':
                        case '\r':
                        case '\n':
                            indent_char = indent_str[0];
                            break;
                        default:
                            rb_raise(rb_eUsaminError, ":indent must be a repetation of \" \", \"\\t\", \"\\r\" or \"\\n\".");
                    }
                    for (long i = 1; i < vlen; i++)
                        if (indent_str[0] != indent_str[i])
                            rb_raise(rb_eUsaminError, ":indent must be a repetation of \" \", \"\\t\", \"\\r\" or \"\\n\".");
                    indent_count = static_cast<unsigned int>(vlen);
                }
            }
        }

        if (RTEST(rb_hash_lookup(options, sym_single_line_array)))
            writer.SetFormatOptions(rapidjson::kFormatSingleLineArray);
    }
    writer.SetIndent(indent_char, indent_count);

    write(writer, value);
    return new_utf8_str(buf.GetString(), buf.GetSize());
}