Login
Artifact [8906623f02]
Login

Artifact 8906623f02287a60b6370935df1e5ef43c7949dc:


requireS2(['json2'],proc(JSON){
    //JSON.stringify.config.indention = -1;
    const str = proc(v,indent=-1){
        return JSON.stringify(v,indent);
    };
    var s;
    assert '1' === str(1);
    assert '1.23' === str(1.23);
    assert '"hi, \\"there\\""' === str('hi, "there"');
    assert 'null' === str(null);
    assert 'null' === str(undefined)
    /* undefined will be elided in some contexts (object properties),
       translated to null in others (e.g. arrays). */;
    assert 'false' === str(false);
    assert 'true' === str(true);
    s = str({x:1, y:{z:'hi "there"', a:[1,2,"yo"]}, u: undefined, n: null});
    assert s.indexOf('"u":') < 0;
    assert s.indexOf('"n": null')>0;

    s = JSON.parse(str(exception(-1,"not an error")));
    assert 'not an error' === s.message;
    assert -1 === s.code;

    s = JSON.parse(str({a:{b:{1:2,3:4}}}));
    assert 2 === s.a.b.'1';
    assert 4 === s.a.b.'3'
    /**
       BUT ACHTUNG: the integer _keys_ got converted to strings in the
       round trip because JSON only supports strings as
       keys. Supporting round-trip fideltity for non-string keys
       requires a layer of indirection, as demonstrated next...
    */;

    // Customizing toJSON for a non-POD type...
    var h = s2.Hash.new();

    // A stringify()-compliant toJSON() impl for Hashtables.
    h.toJSON = proc(){
        return {
            keys: this.entryKeys(),
            values: this.entryValues()
        }
    };

    // Just for symmetry (not used by the JSON API)...
    h.fromJSON = proc(jsonObj){
        ('string' === typename jsonObj) && (jsonObj = JSON.parse(jsonObj));
        this.clearEntries();
        if(('array' === typename jsonObj.keys) &&
           ('array' === typename jsonObj.values)){
            const that = this;
            jsonObj.keys.eachIndex(proc(v,i){
                that.insert(v, jsonObj.values[i]);
            });
        }
        return this;
    }.importSymbols(nameof JSON);

    // Now try serializing a hash...
    h.insert(1, "one");
    h.insert(2, "two");
    s = JSON.parse(str(h));
    assert 2 === s.keys.length();
    assert 2 === s.values.length();
    assert s.keys.indexOf(2)>=0;
    assert s.values.indexOf('two')>=0;

    h.clearEntries();
    assert undefined === h # 2;

    h.fromJSON(s);
    assert 'two' === h # 2;
    
});