@@ -16,6 +16,7 @@ import mir.small_array;
1616import mir.small_string;
1717import mir.utility: _expect;
1818import std.traits : ForeachType, hasUDA, Unqual, isSomeChar, EnumMembers, TemplateArgsOf, getUDAs;
19+ import mir.ion.conv : toProxy;
1920
2021private alias AliasSeq (T... ) = T;
2122
@@ -380,7 +381,7 @@ template deserializeValue(string[] symbolTable)
380381 Temporal proxy;
381382 if (auto exception = impl(params, proxy))
382383 return exception;
383- auto temporal = to ! (serdeDeserializationMemberType! (T, member))(move(proxy));
384+ auto temporal = toProxy ! (serdeDeserializationMemberType! (T, member))(move(proxy));
384385 static if (hasTransform)
385386 transform(temporal);
386387 __traits (getMember , value, member) = move(temporal);
@@ -442,6 +443,7 @@ template deserializeValue(string[] symbolTable)
442443 if (! isFirstOrderSerdeType! T)
443444 {with (params){
444445 import mir.algebraic: isVariant, isNullable;
446+ import mir.serde: ContainsProxied;
445447 import mir.internal.meta: Contains;
446448 import mir.ndslice.slice: Slice, SliceKind;
447449 import mir.rc.array: RCArray, RCI ;
@@ -749,7 +751,6 @@ template deserializeValue(string[] symbolTable)
749751 return error.ionException;
750752 if (symbolId >= table.length)
751753 return IonErrorCode.symbolIdIsTooLargeForTheCurrentSymbolTable.ionException;
752- import mir.conv: to;
753754 auto elemParams = params.withData(elem);
754755 serdeGetProxy! T temporal;
755756 if (auto exception = impl(elemParams, temporal))
@@ -774,7 +775,6 @@ template deserializeValue(string[] symbolTable)
774775 {
775776 if (error)
776777 return error.ionException;
777- import mir.conv: to;
778778 auto elemParams = params.withData(elem);
779779 serdeGetProxy! T temporal;
780780 if (auto exception = impl(elemParams, temporal))
@@ -788,7 +788,7 @@ template deserializeValue(string[] symbolTable)
788788 if (auto exception = impl(params, temporal))
789789 return exception;
790790
791- value = to ! T(move(temporal));
791+ value = toProxy ! T(move(temporal));
792792 }
793793 static if (__traits(hasMember, T, " serdeFinalize" ))
794794 {
@@ -876,7 +876,26 @@ template deserializeValue(string[] symbolTable)
876876 }
877877
878878 alias Types = T.AllowedTypes;
879- alias contains = Contains! Types;
879+ alias contains = ContainsProxied! Types;
880+
881+ pragma (inline, true ) void setValue(T)(T new_value)
882+ {
883+ alias realContains = Contains! Types;
884+ static if (realContains! T)
885+ value = new_value;
886+ else
887+ {
888+ static foreach (Type; Types)
889+ {
890+ static if (is (serdeGetFinalProxy! Type == T))
891+ {
892+ Type ret = new_value.toProxy! Type;
893+ value = ret;
894+ return ; // kind of unsafe: first one wins, but compiler will warn with multiple returns anyway
895+ }
896+ }
897+ }
898+ }
880899
881900 static if (getAlgebraicAnnotationsOfVariant! T.length)
882901 {
@@ -901,7 +920,7 @@ template deserializeValue(string[] symbolTable)
901920 if (auto exception = deserializeValue(annotatedParams, object))
902921 return exception;
903922 import core.lifetime : move;
904- value = move(object);
923+ setValue( move(object) );
905924 return null ;
906925 }
907926 }
@@ -936,7 +955,7 @@ template deserializeValue(string[] symbolTable)
936955 if (auto exception = deserializeValue(annotatedParams, object))
937956 return exception;
938957 import core.lifetime : move;
939- value = move(object);
958+ setValue( move(object) );
940959 return null ;
941960 }
942961 }
@@ -951,7 +970,7 @@ template deserializeValue(string[] symbolTable)
951970 // TODO: check that descriptor.type correspond underlaying type
952971 if (data.descriptor.L == 0xF )
953972 {
954- value = IonNull(data.descriptor.type);
973+ setValue( IonNull(data.descriptor.type) );
955974 return retNull;
956975 }
957976 }
@@ -961,7 +980,7 @@ template deserializeValue(string[] symbolTable)
961980 // TODO: check that descriptor.type correspond underlaying type
962981 if (data.descriptor.L == 0xF )
963982 {
964- value = null ;
983+ setValue( null ) ;
965984 return retNull;
966985 }
967986 }
@@ -970,7 +989,7 @@ template deserializeValue(string[] symbolTable)
970989 T.AllowedTypes[1 ] payload;
971990 if (auto exception = deserializeValue(params, payload))
972991 return exception;
973- value = payload;
992+ setValue( payload) ;
974993 return retNull;
975994 }
976995 else
@@ -980,7 +999,7 @@ template deserializeValue(string[] symbolTable)
980999 // {
9811000 // case IonTypeCode.null_:
9821001 // {
983- // value = null;
1002+ // setValue( null) ;
9841003 // return retNull;
9851004 // }
9861005 // }
@@ -992,7 +1011,7 @@ template deserializeValue(string[] symbolTable)
9921011 bool boolean;
9931012 if (auto errorCode = data.get ! bool (boolean))
9941013 return errorCode.ionException;
995- value = boolean;
1014+ setValue( boolean) ;
9961015 return retNull;
9971016 }
9981017 }
@@ -1005,7 +1024,7 @@ template deserializeValue(string[] symbolTable)
10051024 string str;
10061025 if (auto exception = deserializeValue(params, str))
10071026 return exception;
1008- value = str;
1027+ setValue( str) ;
10091028 return retNull;
10101029 }
10111030 }
@@ -1018,27 +1037,37 @@ template deserializeValue(string[] symbolTable)
10181037 Filter! (isSmallString, Types)[$ - 1 ] str; // pick the largest one
10191038 if (auto exception = deserializeValue(params, str))
10201039 return exception;
1021- value = str;
1040+ setValue( str) ;
10221041 return retNull;
10231042 }
10241043 }
10251044
1026- static if (contains! long )
1045+ enum containsIntegral = contains! short
1046+ || contains! ushort
1047+ || contains! int
1048+ || contains! uint
1049+ || contains! long
1050+ || contains! ulong ;
1051+ enum containsFloating = contains! float
1052+ || contains! double
1053+ || contains! real ;
1054+
1055+ static if (containsIntegral)
10271056 {
10281057 case IonTypeCode.nInt:
10291058 case IonTypeCode.uInt:
10301059 {
10311060 long number;
10321061 if (auto exception = deserializeValue_(data, number))
10331062 return exception;
1034- value = number;
1063+ setValue( number) ;
10351064 return retNull;
10361065 }
10371066 }
10381067
1039- static if (contains ! double )
1068+ static if (containsFloating )
10401069 {
1041- static if (! contains ! long )
1070+ static if (! containsIntegral )
10421071 {
10431072 case IonTypeCode.nInt:
10441073 case IonTypeCode.uInt:
@@ -1049,7 +1078,7 @@ template deserializeValue(string[] symbolTable)
10491078 double number;
10501079 if (auto exception = deserializeValue_(data, number))
10511080 return exception;
1052- value = number;
1081+ setValue( number) ;
10531082 return retNull;
10541083 }
10551084 }
@@ -1061,7 +1090,7 @@ template deserializeValue(string[] symbolTable)
10611090 Timestamp timestamp;
10621091 if (auto error = data.trustedGet! IonTimestamp.get (timestamp))
10631092 return error.ionException;
1064- value = timestamp;
1093+ setValue( timestamp) ;
10651094 return retNull;
10661095 }
10671096 }
@@ -1071,7 +1100,7 @@ template deserializeValue(string[] symbolTable)
10711100 case IonTypeCode.blob:
10721101 {
10731102 auto blob = data.trustedGet! Blob;
1074- value = Blob(blob.data.dup );
1103+ setValue( Blob(blob.data.dup ) );
10751104 return retNull;
10761105 }
10771106 }
@@ -1081,7 +1110,7 @@ template deserializeValue(string[] symbolTable)
10811110 case IonTypeCode.clob:
10821111 {
10831112 auto clob = data.trustedGet! Clob;
1084- value = Clob(clob.data.dup );
1113+ setValue( Clob(clob.data.dup ) );
10851114 return retNull;
10861115 }
10871116 }
@@ -1096,7 +1125,7 @@ template deserializeValue(string[] symbolTable)
10961125 if (auto exception = deserializeValue(params, array))
10971126 return exception;
10981127 import core.lifetime : move;
1099- value = move(array);
1128+ setValue( move(array) );
11001129 return retNull;
11011130 }
11021131 }
@@ -1164,7 +1193,7 @@ template deserializeValue(string[] symbolTable)
11641193 if (auto exception = deserializeValue(params, object))
11651194 return exception;
11661195 import core.lifetime : move;
1167- value = move(object);
1196+ setValue( move(object) );
11681197 return retNull;
11691198 }
11701199 }
@@ -1186,7 +1215,7 @@ template deserializeValue(string[] symbolTable)
11861215 if (auto exception = deserializeValue(params, object))
11871216 return exception;
11881217 import core.lifetime : move;
1189- value = move(object);
1218+ setValue( move(object) );
11901219 return retNull;
11911220 }
11921221 }
@@ -1202,7 +1231,7 @@ template deserializeValue(string[] symbolTable)
12021231 if (auto exception = deserializeValue(params, object))
12031232 return exception;
12041233 import core.lifetime : move;
1205- value = move(object);
1234+ setValue( move(object) );
12061235 return retNull;
12071236 }
12081237 }
0 commit comments