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