diff --git a/dub.sdl b/dub.sdl index 36b8b24..f5db035 100644 --- a/dub.sdl +++ b/dub.sdl @@ -3,7 +3,7 @@ description "Fast, Expressive, and Easy to use Ion, JSON, YAML, CSV, and Msgpack authors "Ilia Ki (Asdf & Mir Ion) " "Yannick Koechlin (Asdf)" copyright "Tamedia Digital, 2016, Symmetry Investments and Kaleidic Associates, 2020, Symmetry Investments and Ilia Ki 2021-" license "Apache-2.0" -dependency "mir-algorithm" version=">=3.21.0" +dependency "mir-algorithm" version=">=3.22.1" dependency "mir-cpuid" version="~>1.2.6" configuration "library" { diff --git a/source/mir/ser/cbor.d b/source/mir/ser/cbor.d index e54570d..894156d 100644 --- a/source/mir/ser/cbor.d +++ b/source/mir/ser/cbor.d @@ -616,6 +616,31 @@ version(mir_ion_test) unittest serializeCbor(book).should == [0xBF, 0x65, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x72, 0x41, 0x20, 0x48, 0x65, 0x72, 0x6F, 0x20, 0x6F, 0x66, 0x20, 0x4F, 0x75, 0x72, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x6E, 0x77, 0x6F, 0x75, 0x6C, 0x64, 0x52, 0x65, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x6E, 0x64, 0xF5, 0x6B, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x60, 0x70, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x4F, 0x66, 0x4E, 0x6F, 0x76, 0x65, 0x6C, 0x6C, 0x61, 0x73, 0x05, 0x65, 0x70, 0x72, 0x69, 0x63, 0x65, 0xFB, 0x40, 0x1F, 0xF5, 0xC2, 0x8F, 0x5C, 0x28, 0xF6, 0x66, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0xFA, 0x40, 0xDC, 0x28, 0xF6, 0x64, 0x74, 0x61, 0x67, 0x73, 0x83, 0x67, 0x72, 0x75, 0x73, 0x73, 0x69, 0x61, 0x6E, 0x65, 0x6E, 0x6F, 0x76, 0x65, 0x6C, 0x6C, 0x31, 0x39, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x75, 0x72, 0x79, 0xFF]; } +/// Test maps with serdeMembersExactly +@safe pure +version(mir_ion_test) unittest +{ + import mir.test; + import mir.serde: serdeMembersExactly; + + @serdeMembersExactly(7) + struct Book + { + string title; + bool wouldRecommend; + string description; + uint numberOfNovellas; + double price; + float weight; + string[] tags; + } + + Book book = Book("A Hero of Our Time", true, "", 5, 7.99, 6.88, ["russian", "novel", "19th century"]); + + // This will probably break if you modify how any of the data types + // are serialized. + serializeCbor(book).should == [0xA7, 0x65, 0x74, 0x69, 0x74, 0x6C, 0x65, 0x72, 0x41, 0x20, 0x48, 0x65, 0x72, 0x6F, 0x20, 0x6F, 0x66, 0x20, 0x4F, 0x75, 0x72, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x6E, 0x77, 0x6F, 0x75, 0x6C, 0x64, 0x52, 0x65, 0x63, 0x6F, 0x6D, 0x6D, 0x65, 0x6E, 0x64, 0xF5, 0x6B, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x60, 0x70, 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0x4F, 0x66, 0x4E, 0x6F, 0x76, 0x65, 0x6C, 0x6C, 0x61, 0x73, 0x05, 0x65, 0x70, 0x72, 0x69, 0x63, 0x65, 0xFB, 0x40, 0x1F, 0xF5, 0xC2, 0x8F, 0x5C, 0x28, 0xF6, 0x66, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0xFA, 0x40, 0xDC, 0x28, 0xF6, 0x64, 0x74, 0x61, 0x67, 0x73, 0x83, 0x67, 0x72, 0x75, 0x73, 0x73, 0x69, 0x61, 0x6E, 0x65, 0x6E, 0x6F, 0x76, 0x65, 0x6C, 0x6C, 0x31, 0x39, 0x74, 0x68, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x75, 0x72, 0x79]; +} /// Test serializing annotated structs @safe pure diff --git a/source/mir/ser/package.d b/source/mir/ser/package.d index f726b46..d4a9238 100644 --- a/source/mir/ser/package.d +++ b/source/mir/ser/package.d @@ -466,7 +466,7 @@ private void serializeValueImpl(S, V)(scope ref S serializer, scope ref const V if (isAggregateType!V && (!isIterable!V || hasFields!V || hasUDA!(V, serdeProxy) && !hasUDA!(V, serdeLikeList))) { import mir.algebraic; - auto state = serializer.structBegin; + auto state = serializer.beginStruct(value); static if (hasUDA!(V, serdeDiscriminatedField)) {{ @@ -1303,6 +1303,13 @@ auto beginStruct(S, V)(scope ref S serializer, scope ref V value) return serializer.structBegin(value.length); } else + static if (hasUDA!(V, serdeMembersExactly)) + { + enum auto udas = getUDAs!(V, serdeMembersExactly); + static assert(udas.length == 1, V.stringof ~ " can have exactly one UDA serdeMembersExactly"); + return serializer.structBegin(getUDAs!(V, serdeMembersExactly)[0].n); + } + else static if (__traits(compiles, serializer.structBegin)) { return serializer.structBegin;