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