1 /++ 2 $(H1 Mutable JSON value) 3 4 This module contains a single alias definition and doesn't provide JSON serialization API. 5 6 See_also: JSON libraries $(MIR_PACKAGE mir-ion) and $(MIR_PACKAGE asdf); 7 8 License: $(HTTP www.apache.org/licenses/LICENSE-2.0, Apache-2.0) 9 Authors: Ilia Ki 10 Macros: 11 +/ 12 module mir.algebraic_alias.json; 13 14 import mir.algebraic: Algebraic, This; 15 /// 16 public import mir.string_map: StringMap; 17 18 /++ 19 Definition union for $(LREF JsonAlgebraic). 20 +/ 21 union Json_ 22 { 23 /// 24 typeof(null) null_; 25 /// 26 bool boolean; 27 /// 28 long integer; 29 /// 30 double float_; 31 /// 32 immutable(char)[] string; 33 /// Self alias in array. 34 This[] array; 35 /// Self alias in $(MREF mir,string_map). 36 StringMap!This object; 37 } 38 39 /++ 40 JSON tagged algebraic alias. 41 42 The example below shows only the basic features. Advanced API to work with algebraic types can be found at $(GMREF mir-core, mir,algebraic). 43 See also $(MREF mir,string_map) - ordered string-value associative array. 44 +/ 45 alias JsonAlgebraic = Algebraic!Json_; 46 47 /// 48 version(mir_test) 49 @safe pure 50 unittest 51 { 52 import mir.test: should; 53 import mir.ndslice.topology: map; 54 import mir.array.allocation: array; 55 56 JsonAlgebraic value; 57 58 StringMap!JsonAlgebraic object; 59 60 // Default 61 assert(value.isNull); 62 assert(value.kind == JsonAlgebraic.Kind.null_); 63 64 // Boolean 65 value = object["bool"] = true; 66 assert(!value.isNull); 67 assert(value == true); 68 assert(value.kind == JsonAlgebraic.Kind.boolean); 69 // access 70 assert(value.boolean == true); 71 assert(value.get!bool == true); 72 assert(value.get!"boolean" == true); 73 assert(value.get!(JsonAlgebraic.Kind.boolean) == true); 74 // nothrow access 75 assert(value.trustedGet!bool == true); 76 assert(value.trustedGet!"boolean" == true); 77 assert(value.trustedGet!(JsonAlgebraic.Kind.boolean) == true); 78 // checks 79 assert(!value._is!string); 80 assert(value._is!bool); 81 assert(value._is!"boolean"); 82 assert(value._is!(JsonAlgebraic.Kind.boolean)); 83 84 // Null 85 value = object["null"] = null; 86 assert(value.isNull); 87 assert(value == null); 88 assert(value.kind == JsonAlgebraic.Kind.null_); 89 // access 90 assert(value.null_ == null); 91 assert(value.get!(typeof(null)) == null); 92 assert(value.get!(JsonAlgebraic.Kind.null_) == null); 93 94 // String 95 value = object["string"] = "s"; 96 assert(value.kind == JsonAlgebraic.Kind..string); 97 assert(value == "s"); 98 // access 99 // Yep, `string` here is an alias to `get!(immutable(char)[])` method 100 assert(value..string == "s"); 101 // `string` here is an alias of type `immutable(char)[]` 102 assert(value.get!string == "s"); 103 assert(value.get!"string" == "s"); 104 // finally, `string` here is an enum meber 105 assert(value.get!(JsonAlgebraic.Kind..string) == "s"); 106 107 // Integer 108 value = object["integer"] = 4; 109 assert(value.kind == JsonAlgebraic.Kind.integer); 110 assert(value == 4); 111 assert(value != 4.0); 112 assert(value.integer == 4); 113 114 // Float 115 value = object["float"] = 3.0; 116 assert(value.kind == JsonAlgebraic.Kind.float_); 117 assert(value != 3); 118 assert(value == 3.0); 119 assert(value.float_ == 3.0); 120 121 // Array 122 JsonAlgebraic[] arr = [0, 1, 2, 3, 4].map!JsonAlgebraic.array; 123 124 value = object["array"] = arr; 125 assert(value.kind == JsonAlgebraic.Kind.array); 126 assert(value == arr); 127 assert(value.array[3] == 3); 128 129 // Object 130 assert(object.keys == ["bool", "null", "string", "integer", "float", "array"]); 131 object.values[0] = "false"; 132 assert(object["bool"] == "false"); // it is a string now 133 object.remove("bool"); // remove the member 134 135 value = object["array"] = object; 136 assert(value.kind == JsonAlgebraic.Kind.object); 137 assert(value.object.keys is object.keys); 138 139 JsonAlgebraic[string] aa = object.toAA; 140 object = aa.StringMap!JsonAlgebraic; 141 142 JsonAlgebraic fromAA = ["a" : JsonAlgebraic(3), "b" : JsonAlgebraic("b")]; 143 assert(fromAA.object["a"] == 3); 144 assert(fromAA.object["b"] == "b"); 145 146 // object foreach iteration 147 long sum; 148 foreach (ref key, ref val; fromAA.object) 149 if (key == "a") 150 sum += val.get!long; 151 sum.should == 3; 152 }