libmir/mir-ion

Unexpected IonTypeCode with deserializeIon!(Variant!T)

WebFreak001 opened this issue · 4 comments

Reproduction case: (I have SumType as custom type which defines serdeIgnoreOut)

import std.stdio;
import mir.ser.json : serializeJson;
import mir.deser.json : deserializeDynamicJson;

struct SumType(Types...)
{
	import std.sumtype : StdSumType = SumType, match;
	import mir.ion.exception;
	import mir.ion.value;

	StdSumType!Types value;
	alias value this;

	this(T)(T v)
	{
		value = typeof(value)(v);
	}

	void serialize(S)(ref S serializer) const
	{
		import mir.ser : serializeValue;

		value.match!(v => serializeValue(serializer, v));
	}

	IonException deserializeFromIon(scope const char[][] symbolTable, IonDescribedValue inputValue)
	{
		import mir.deser.ion : deserializeIon;
		import mir.algebraic : Variant, match;

		auto alg = deserializeIon!(Variant!Types)(symbolTable, inputValue);
		alg.match!(v => value = v);
		return null;
	}
}

struct Location
{
	string uri;
}

alias LocValue = SumType!(Location[], Location);

void main()
{
	auto v = LocValue(Location("file:///foo.d"));
	auto serialized = v.serializeJson;
	writeln(serialized);
	assert(deserializeDynamicJson!LocValue(serialized) == v);
}
Running a 
{"uri":"file:///foo.d"}
mir.ion.exception.IonException@/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/package.d(1230): Unexpected IonTypeCode for Algebraic!(Location[], Location)
----------------
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/ion.d:60 pure @safe void mir.deser.ion.deserializeIon!(mir.algebraic.Algebraic!(app.Location[], app.Location).Algebraic, false).deserializeIon!().deserializeIon(ref mir.algebraic.Algebraic!(app.Location[], app.Location).Algebraic, scope const(char[][]), mir.ion.value.IonDescribedValue) [0x557dd89137a1]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/ion.d:29 pure @safe mir.algebraic.Algebraic!(app.Location[], app.Location).Algebraic mir.deser.ion.deserializeIon!(mir.algebraic.Algebraic!(app.Location[], app.Location).Algebraic, false).deserializeIon!().deserializeIon(scope const(char[][]), mir.ion.value.IonDescribedValue) [0x557dd891364c]
source/app.d:31 pure mir.ion.exception.IonException app.SumType!(app.Location[], app.Location).SumType.deserializeFromIon(scope const(char[][]), mir.ion.value.IonDescribedValue) [0x557dd890ca51]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/package.d:479 pure mir.ion.exception.IonException mir.deser.deserializeValue!(null).deserializeValue!(app.SumType!(app.Location[], app.Location).SumType, 1, false).deserializeValue(mir.deser.DeserializationParams!(1, false).DeserializationParams, ref app.SumType!(app.Location[], app.Location).SumType) [0x557dd891319a]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/ion.d:59 pure void mir.deser.ion.deserializeIon!(app.SumType!(app.Location[], app.Location).SumType, false).deserializeIon!().deserializeIon(ref app.SumType!(app.Location[], app.Location).SumType, scope const(char[][]), mir.ion.value.IonDescribedValue) [0x557dd891187f]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/ion.d:126 pure int mir.deser.ion.deserializeIon!(app.SumType!(app.Location[], app.Location).SumType, false).deserializeIon!().deserializeIon(ref app.SumType!(app.Location[], app.Location).SumType, scope const(ubyte)[]).__foreachbody3(const(char[])[], mir.ion.value.IonDescribedValue) [0x557dd8911740]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/ion/stream.d:42 pure @nogc @safe int mir.ion.stream.IonValueStream.opApply(scope int delegate(const(char[])[], mir.ion.value.IonDescribedValue) pure @nogc @safe).__lambda2(mir.ion.exception.IonErrorCode, const(char[])[], mir.ion.value.IonDescribedValue) [0x557dd891ef70]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/ion/stream.d:233 const pure nothrow @nogc scope @trusted int mir.ion.stream.IonValueStream.opApply(scope int delegate(mir.ion.exception.IonErrorCode, const(char[])[], mir.ion.value.IonDescribedValue) pure nothrow @nogc @safe) [0x557dd891f3b6]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/ion/stream.d:247 const pure @nogc scope @trusted int mir.ion.stream.IonValueStream.opApply(scope int delegate(mir.ion.exception.IonErrorCode, const(char[])[], mir.ion.value.IonDescribedValue) pure @nogc @safe) [0x557dd891f737]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/ion/stream.d:39 const pure @nogc scope @safe int mir.ion.stream.IonValueStream.opApply(scope int delegate(const(char[])[], mir.ion.value.IonDescribedValue) pure @nogc @safe) [0x557dd891ef0a]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/ion/stream.d:74 const pure scope int mir.ion.stream.IonValueStream.opApply(scope int delegate(const(char[])[], mir.ion.value.IonDescribedValue) pure) [0x557dd891f093]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/ion.d:124 pure void mir.deser.ion.deserializeIon!(app.SumType!(app.Location[], app.Location).SumType, false).deserializeIon!().deserializeIon(ref app.SumType!(app.Location[], app.Location).SumType, scope const(ubyte)[]) [0x557dd89116e5]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/json.d:417 pure void mir.deser.json.deserializeDynamicJson!(app.SumType!(app.Location[], app.Location).SumType).deserializeDynamicJson(ref app.SumType!(app.Location[], app.Location).SumType, scope const(char)[]) [0x557dd89116a2]
/home/webfreak/.dub/packages/mir-ion-1.0.31/mir-ion/source/mir/deser/json.d:408 pure app.SumType!(app.Location[], app.Location).SumType mir.deser.json.deserializeDynamicJson!(app.SumType!(app.Location[], app.Location).SumType).deserializeDynamicJson(scope const(char)[]) [0x557dd891165f]
source/app.d:49 _Dmain [0x557dd890c9a1]
Program exited with code 1
9il commented

Fix:

import mir.serde : serdeFallbackStruct;
@serdeFallbackStruct
struct Location
{
	string uri;
}

BTW, find examples with @serdeProxy in source code. That will simplify you example a lot.

do I need to put @serdeFallbackStruct on all my structs?

9il commented

A required UDA is depends on how do you group them inside the Variant.

BTW, why do you need your own algebraic template?

9il commented

Or Std algebraic. Could you use Mir or something doesn't work for you?