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.7"

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)


1271
1272
1273
1274
1275
1276
# File 'ext/usamin/usamin.cpp', line 1271

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)


436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# File 'ext/usamin/usamin.cpp', line 436

static VALUE w_load(const int argc, const VALUE *argv, const VALUE self) {
    VALUE source, options;
    rb_scan_args(argc, argv, "1:", &source, &options);
    rapidjson::Document *doc = new rapidjson::Document;
    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));
        case rapidjson::kArrayType:
            return make_array(new UsaminValue(doc, 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)


484
485
486
487
488
489
490
491
492
# File 'ext/usamin/usamin.cpp', line 484

static VALUE w_parse(const int argc, const VALUE *argv, const VALUE self) {
    VALUE source, options;
    rb_scan_args(argc, argv, "1:", &source, &options);
    rapidjson::Document 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)


1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
# File 'ext/usamin/usamin.cpp', line 1288

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());
}