From c0d9b24cc4200b401796935fa646706fb78c26eb Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Mon, 11 Nov 2024 18:31:36 +0000 Subject: [PATCH 01/10] First pass --- Vogen.sln.DotSettings | 1 + src/Vogen.SharedTypes/Conversions.cs | 7 +- .../EfCoreConverterAttribute.cs | 8 +- src/Vogen.SharedTypes/MessagePackAttribute.cs | 12 ++ ...nverterMarkerDefinitionsFromAttributes.cs} | 11 +- .../ConversionMarkerAttributeDefinition.cs | 35 ++++++ src/Vogen/ConversionMarkerClassDefinition.cs | 25 +++++ src/Vogen/ConversionMarkers.cs | 49 ++++++++ ...oreConverterSpec.cs => ConverterMarker.cs} | 8 +- .../EfCoreConverterMarkerClassResults.cs | 25 ----- src/Vogen/EfCoreConverterSpecResult.cs | 29 ----- ...cs => GenerateCodeForConversionMarkers.cs} | 33 ++++-- src/Vogen/GenerateCodeForMessagePack.cs | 106 ++++++++++++++++++ .../GenerateCodeForMessagePackMarkers.cs | 36 ++++++ .../Conversions/GenerateEfCoreTypes.cs | 2 +- src/Vogen/ManageAttributes.cs | 14 --- src/Vogen/ValueObjectGenerator.cs | 26 +++-- .../GeneralStuff/GeneralTests.cs | 46 ++++++++ ...alTests.Generates_messagepack.verified.txt | 1 + ...Generates_messagepack_markers.verified.txt | 1 + tests/Testbench/EfCoreTest/EfCoreScenario.cs | 76 ------------- tests/Testbench/EfCoreTest/TypesAndModels.cs | 103 ----------------- .../20241021092427_Initial.Designer.cs | 49 -------- .../Migrations/20241021092427_Initial.cs | 37 ------ .../Migrations/MyContextModelSnapshot.cs | 46 -------- tests/Testbench/Program.cs | 73 +----------- tests/Testbench/Testbench.csproj | 1 + 27 files changed, 378 insertions(+), 482 deletions(-) create mode 100644 src/Vogen.SharedTypes/MessagePackAttribute.cs rename src/Vogen/{BuildEfCoreConverterSpecsFromAttributes.cs => BuildConverterMarkerDefinitionsFromAttributes.cs} (74%) create mode 100644 src/Vogen/ConversionMarkerAttributeDefinition.cs create mode 100644 src/Vogen/ConversionMarkerClassDefinition.cs create mode 100644 src/Vogen/ConversionMarkers.cs rename src/Vogen/{EfCoreConverterSpec.cs => ConverterMarker.cs} (60%) delete mode 100644 src/Vogen/EfCoreConverterMarkerClassResults.cs delete mode 100644 src/Vogen/EfCoreConverterSpecResult.cs rename src/Vogen/{GenerateCodeForEfCoreSpecs.cs => GenerateCodeForConversionMarkers.cs} (72%) create mode 100644 src/Vogen/GenerateCodeForMessagePack.cs create mode 100644 src/Vogen/GenerateCodeForMessagePackMarkers.cs create mode 100644 tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt create mode 100644 tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt delete mode 100644 tests/Testbench/EfCoreTest/EfCoreScenario.cs delete mode 100644 tests/Testbench/EfCoreTest/TypesAndModels.cs delete mode 100644 tests/Testbench/Migrations/20241021092427_Initial.Designer.cs delete mode 100644 tests/Testbench/Migrations/20241021092427_Initial.cs delete mode 100644 tests/Testbench/Migrations/MyContextModelSnapshot.cs diff --git a/Vogen.sln.DotSettings b/Vogen.sln.DotSettings index c8dbce8f81..276398dab3 100644 --- a/Vogen.sln.DotSettings +++ b/Vogen.sln.DotSettings @@ -57,6 +57,7 @@ True True True + True True True True diff --git a/src/Vogen.SharedTypes/Conversions.cs b/src/Vogen.SharedTypes/Conversions.cs index 3d03f0cdbd..daec65eabd 100644 --- a/src/Vogen.SharedTypes/Conversions.cs +++ b/src/Vogen.SharedTypes/Conversions.cs @@ -71,5 +71,10 @@ public enum Conversions /// /// Generates implementation of IXmlSerializable. /// - XmlSerializable = 1 << 10 + XmlSerializable = 1 << 10, + + /// + /// Generates implementation of IMessagePackFormatter. + /// + MessagePack = 1 << 11 } \ No newline at end of file diff --git a/src/Vogen.SharedTypes/EfCoreConverterAttribute.cs b/src/Vogen.SharedTypes/EfCoreConverterAttribute.cs index 66d822eddc..51931a6c32 100644 --- a/src/Vogen.SharedTypes/EfCoreConverterAttribute.cs +++ b/src/Vogen.SharedTypes/EfCoreConverterAttribute.cs @@ -2,7 +2,13 @@ namespace Vogen; + + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public class EfCoreConverterAttribute : Attribute +public class EfCoreConverterAttribute : ConversionMarkerAttribute +{ +} + +public class ConversionMarkerAttribute : Attribute { } \ No newline at end of file diff --git a/src/Vogen.SharedTypes/MessagePackAttribute.cs b/src/Vogen.SharedTypes/MessagePackAttribute.cs new file mode 100644 index 0000000000..94fcf33956 --- /dev/null +++ b/src/Vogen.SharedTypes/MessagePackAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Vogen; + +/// +/// Represent a marker for MessagePack generation. +/// +/// The type of the value object. +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] +public class MessagePackAttribute : ConversionMarkerAttribute +{ +} \ No newline at end of file diff --git a/src/Vogen/BuildEfCoreConverterSpecsFromAttributes.cs b/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs similarity index 74% rename from src/Vogen/BuildEfCoreConverterSpecsFromAttributes.cs rename to src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs index 609f176f46..c9fcdec82e 100644 --- a/src/Vogen/BuildEfCoreConverterSpecsFromAttributes.cs +++ b/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs @@ -8,10 +8,9 @@ namespace Vogen; -internal static class BuildEfCoreConverterSpecsFromAttributes +internal static class BuildConverterMarkerDefinitionsFromAttributes { - - public static EfCoreConverterSpecResult? TryBuild(AttributeData att, in INamedTypeSymbol? markerClassSymbol) + public static ConversionMarkerAttributeDefinition? TryBuild(AttributeData att, in INamedTypeSymbol? markerClassSymbol) { ImmutableArray args = att.ConstructorArguments; @@ -44,7 +43,7 @@ internal static class BuildEfCoreConverterSpecsFromAttributes if (!VoFilter.IsTarget(voSymbol)) { - return EfCoreConverterSpecResult.Error(DiagnosticsCatalogue.EfCoreTargetMustBeAVo(markerClassSymbol!, voSymbol)); + return ConversionMarkerAttributeDefinition.Error(ConverterMarkerKind.EFCore, DiagnosticsCatalogue.EfCoreTargetMustBeAVo(markerClassSymbol!, voSymbol)); } List attrs = VoFilter.TryGetValueObjectAttributes(voSymbol).ToList(); @@ -63,10 +62,10 @@ internal static class BuildEfCoreConverterSpecsFromAttributes if (underlyingType is null) { - return EfCoreConverterSpecResult.Error(DiagnosticsCatalogue.VoMustExplicitlySpecifyPrimitiveToBeAnEfCoreTarget(voSymbol)); + return ConversionMarkerAttributeDefinition.Error(ConverterMarkerKind.EFCore, DiagnosticsCatalogue.VoMustExplicitlySpecifyPrimitiveToBeAnEfCoreTarget(voSymbol)); } - return EfCoreConverterSpecResult.Ok(voSymbol, underlyingType, markerClassSymbol!); + return ConversionMarkerAttributeDefinition.Ok(ConverterMarkerKind.EFCore, voSymbol, underlyingType, markerClassSymbol!); } private static INamedTypeSymbol? ResolveUnderlyingType(INamedTypeSymbol method) diff --git a/src/Vogen/ConversionMarkerAttributeDefinition.cs b/src/Vogen/ConversionMarkerAttributeDefinition.cs new file mode 100644 index 0000000000..794d25c8b0 --- /dev/null +++ b/src/Vogen/ConversionMarkerAttributeDefinition.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Vogen; + +public enum ConverterMarkerKind +{ + EFCore, + MessagePack, +} + +/// +/// Represents the *definition* of a 'marker attribute, e.g. an 'EFCore marker' or 'memory pack marker' - that is, a partial class decorated with an +/// attribute such as `EfCoreConverter`, or 'MemoryPackConverter'. This is the singular item; a particular attribute on the method, +/// and contains the symbol for the value object being referenced, a symbol for the underlying type of the value object, +/// and a symbol for the method containing the attribute. +/// +internal sealed class ConversionMarkerAttributeDefinition +{ + private ConversionMarkerAttributeDefinition(ConverterMarker? marker, IEnumerable diagnostics) + { + Marker = marker; + Diagnostics = diagnostics.ToList(); + } + + public ConverterMarker? Marker { get; } + + public List Diagnostics { get; } + + public static ConversionMarkerAttributeDefinition Error(ConverterMarkerKind efCore, Diagnostic diag) => new(null, [diag]); + + public static ConversionMarkerAttributeDefinition Ok(ConverterMarkerKind kind, INamedTypeSymbol voSymbol, INamedTypeSymbol underlyingTypeSymbol, INamedTypeSymbol sourceSymbol) => + new(marker: new ConverterMarker(kind, voSymbol, underlyingTypeSymbol, sourceSymbol), diagnostics: []); +} \ No newline at end of file diff --git a/src/Vogen/ConversionMarkerClassDefinition.cs b/src/Vogen/ConversionMarkerClassDefinition.cs new file mode 100644 index 0000000000..f614f6ab7e --- /dev/null +++ b/src/Vogen/ConversionMarkerClassDefinition.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Vogen; + +/// +/// Represents a collection of EFCore converter marker definitions (`EfCoreConverter<>`) that are all associated with the same type symbol +/// (that is, the type containing the `EfCoreConverter` attributes). +/// +internal sealed class ConversionMarkerClassDefinition +{ + public INamedTypeSymbol? MarkerClassSymbol { get; } + + public ConversionMarkerClassDefinition(INamedTypeSymbol? markerClassSymbol, IEnumerable markers) + { + MarkerClassSymbol = markerClassSymbol; + Results = markers.Where(r => r is not null)!; + } + + private IEnumerable Results { get; } + + public IEnumerable Diagnostics => Results.SelectMany(r => r.Diagnostics); + public IEnumerable AttributeDefinitions => Results; +} \ No newline at end of file diff --git a/src/Vogen/ConversionMarkers.cs b/src/Vogen/ConversionMarkers.cs new file mode 100644 index 0000000000..0870a0a928 --- /dev/null +++ b/src/Vogen/ConversionMarkers.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Vogen; + +internal static class ConversionMarkers +{ + /// + /// Tries to get any `ValueObject` attributes specified on the provided symbol. + /// It might return more than one, because the user might have typed more than one. + /// Even though having more than one is not valid, it's still possible for it to exist, + /// so we return what is found and let the caller decide what to do. + /// + /// + /// + public static IEnumerable TryGetMarkerAttributes(INamedTypeSymbol voSymbolInformation) + { + var attrs = voSymbolInformation.GetAttributes(); + + return attrs.Where( + a => a.AttributeClass?.MetadataName == "EfCoreConverterAttribute`1" + || a.AttributeClass?.MetadataName == "MessagePackAttribute`1"); + } + + public static ConversionMarkerClassDefinition? GetConversionMarkerClassDefinitionFromAttribute(GeneratorSyntaxContext context) + { + // var voSyntaxInformation = (TypeDeclarationSyntax) context.Node; + + var semanticModel = context.SemanticModel; + + ISymbol declaredSymbol = semanticModel.GetDeclaredSymbol(context.Node)!; + + var voSymbolInformation = (INamedTypeSymbol) declaredSymbol; + + var attributeData = TryGetMarkerAttributes(voSymbolInformation).ToImmutableArray(); + + if (attributeData.Length == 0) return null; + + return new ConversionMarkerClassDefinition( + voSymbolInformation, + attributeData.Select(a => BuildConverterMarkerDefinitionsFromAttributes.TryBuild(a, voSymbolInformation))); + } + + public static bool IsTarget(SyntaxNode node) => + node is TypeDeclarationSyntax { AttributeLists.Count: > 0 }; +} \ No newline at end of file diff --git a/src/Vogen/EfCoreConverterSpec.cs b/src/Vogen/ConverterMarker.cs similarity index 60% rename from src/Vogen/EfCoreConverterSpec.cs rename to src/Vogen/ConverterMarker.cs index 7feed70577..9a92e1c2bb 100644 --- a/src/Vogen/EfCoreConverterSpec.cs +++ b/src/Vogen/ConverterMarker.cs @@ -3,9 +3,13 @@ namespace Vogen; /// -/// Represents an instance of an EfCoreConverter attribute on the source method. +/// Represents an instance of a marker class attribute, e.g. `EfCoreConverterAttribute` or a `MemoryPackageConverterAttribute`. /// /// The symbol for the value object being referenced. In effect, the generic value of the attribute. /// The symbol for the underlying type that is represented by the value object. /// The symbol for the method that contains the `EfCoreConverter` attribute(s). -internal record EfCoreConverterSpec(INamedTypeSymbol VoSymbol, INamedTypeSymbol UnderlyingType, INamedTypeSymbol SourceType); \ No newline at end of file +internal record ConverterMarker( + ConverterMarkerKind Kind, + INamedTypeSymbol VoSymbol, + INamedTypeSymbol UnderlyingType, + INamedTypeSymbol SourceType); \ No newline at end of file diff --git a/src/Vogen/EfCoreConverterMarkerClassResults.cs b/src/Vogen/EfCoreConverterMarkerClassResults.cs deleted file mode 100644 index 15f6858bcd..0000000000 --- a/src/Vogen/EfCoreConverterMarkerClassResults.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace Vogen; - -/// -/// Represents a collection of results that are all associated with the same source symbol (that is, -/// the method containing the `EfCoreConverter` attributes. -/// -internal sealed class EfCoreConverterMarkerClassResults -{ - public INamedTypeSymbol? MarkerSymbol { get; } - - public EfCoreConverterMarkerClassResults(INamedTypeSymbol? markerSymbol, IEnumerable results) - { - MarkerSymbol = markerSymbol; - Results = results.Where(r => r is not null)!; - } - - private IEnumerable Results { get; } - - public IEnumerable Diagnostics => Results.SelectMany(r => r.Diagnostics); - public IEnumerable Specs => Results; -} \ No newline at end of file diff --git a/src/Vogen/EfCoreConverterSpecResult.cs b/src/Vogen/EfCoreConverterSpecResult.cs deleted file mode 100644 index e00f85761f..0000000000 --- a/src/Vogen/EfCoreConverterSpecResult.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace Vogen; - -/// -/// Represents the result of an 'EFCore Converter Spec' - that is, a partial class decorated with an `EfCoreConverter` -/// attribute. This is the singular item; a particular attribute on the method, and contains the symbol for the -/// value object being references, a symbol for the underlying type of the value object, and a symbol for the method -/// containing the attribute. -/// -internal sealed class EfCoreConverterSpecResult -{ - private EfCoreConverterSpecResult(EfCoreConverterSpec? spec, IEnumerable diagnostics) - { - Spec = spec; - Diagnostics = diagnostics.ToList(); - } - - public EfCoreConverterSpec? Spec { get; } - - public List Diagnostics { get; } - - public static EfCoreConverterSpecResult Error(Diagnostic diag) => new(null, [diag]); - - public static EfCoreConverterSpecResult Ok(INamedTypeSymbol voSymbol, INamedTypeSymbol underlyingTypeSymbol, INamedTypeSymbol sourceSymbol) => - new(spec: new EfCoreConverterSpec(voSymbol, underlyingTypeSymbol, sourceSymbol), diagnostics: []); -} \ No newline at end of file diff --git a/src/Vogen/GenerateCodeForEfCoreSpecs.cs b/src/Vogen/GenerateCodeForConversionMarkers.cs similarity index 72% rename from src/Vogen/GenerateCodeForEfCoreSpecs.cs rename to src/Vogen/GenerateCodeForConversionMarkers.cs index ac210e498e..6465ca1675 100644 --- a/src/Vogen/GenerateCodeForEfCoreSpecs.cs +++ b/src/Vogen/GenerateCodeForConversionMarkers.cs @@ -1,4 +1,6 @@ +using System.Collections.Generic; using System.Collections.Immutable; +using System.Linq; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -7,29 +9,33 @@ namespace Vogen; -internal class GenerateCodeForEfCoreSpecs +internal class GenerateCodeForConversionMarkers { - public static void WriteIfNeeded(SourceProductionContext context, Compilation compilation, ImmutableArray convertSpecs) + public static void Generate(SourceProductionContext context, Compilation compilation, ImmutableArray conversionMarkerClasses) { if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) { return; } - foreach (EfCoreConverterMarkerClassResults? eachMarkerClass in convertSpecs) + foreach (ConversionMarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) { - WriteEncompassingExtensionMethod(eachMarkerClass, context); + var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConverterMarkerKind.EFCore); - foreach (EfCoreConverterSpecResult? eachAttributeInMarkerClass in eachMarkerClass.Specs) + WriteEncompassingExtensionMethod( + eachMarkerClass.MarkerClassSymbol, + matchingMarkers, context); + + foreach (ConversionMarkerAttributeDefinition? eachAttributeInMarkerClass in matchingMarkers) { WriteEachIfNeeded(context, eachAttributeInMarkerClass); } } } - private static void WriteEachIfNeeded(SourceProductionContext context, EfCoreConverterSpecResult specResult) + private static void WriteEachIfNeeded(SourceProductionContext context, ConversionMarkerAttributeDefinition specResult) { - EfCoreConverterSpec? spec = specResult.Spec; + ConverterMarker? spec = specResult.Marker; if (spec is null) { @@ -73,9 +79,12 @@ private static void WriteEachIfNeeded(SourceProductionContext context, EfCoreCon Util.TryWriteUsingUniqueFilename(filename, context, sourceText); } - private static void WriteEncompassingExtensionMethod(EfCoreConverterMarkerClassResults resultsForAMarker, SourceProductionContext context) + private static void WriteEncompassingExtensionMethod( + INamedTypeSymbol? classDefinitionMarkerClassSymbol, + IEnumerable conversionMarkerAttributeDefinitions, + SourceProductionContext context) { - INamedTypeSymbol? markerSymbol = resultsForAMarker.MarkerSymbol; + INamedTypeSymbol? markerSymbol = classDefinitionMarkerClassSymbol; if (markerSymbol is null) { @@ -124,14 +133,14 @@ string GenerateBody() { StringBuilder sb = new StringBuilder(); - foreach (EfCoreConverterSpecResult eachSpec in resultsForAMarker.Specs) + foreach (ConversionMarkerAttributeDefinition eachSpec in conversionMarkerAttributeDefinitions) { - if (eachSpec.Spec is null) + if (eachSpec.Marker is null) { continue; } - var voSymbol = eachSpec.Spec.VoSymbol; + var voSymbol = eachSpec.Marker.VoSymbol; sb.AppendLine($"configurationBuilder.Properties<{voSymbol.FullName()}>().HaveConversion<{markerSymbol.FullName()}.{voSymbol.Name}EfCoreValueConverter, {markerSymbol.FullName()}.{voSymbol.Name}EfCoreValueComparer>();"); } diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs new file mode 100644 index 0000000000..dccee08d36 --- /dev/null +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -0,0 +1,106 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; + +namespace Vogen; + +public record MessagePackGeneratorParams( + string Namespace, + INamedTypeSymbol WrapperType, + INamedTypeSymbol UnderlyingType, + string WrapperAccessibility) +{ + public static MessagePackGeneratorParams FromWorkItem(VoWorkItem voWorkItem) + { + var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); + var accessor = isPublic ? "public" : "internal"; + + return new(voWorkItem.FullNamespace, voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); + } +} + + +internal class GenerateCodeForMessagePack +{ + public static void Generate(SourceProductionContext context, Compilation compilation, List items) + { + if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) + { + return; + } + + List toWrite = items.Select(GenerateSourceAndFilename).ToList(); + + foreach (var eachToWrite in toWrite) + { + SourceText sourceText = SourceText.From(eachToWrite.SourceCode, Encoding.UTF8); + + Util.TryWriteUsingUniqueFilename(eachToWrite.Filename, context, sourceText); + } + } + + public static void GenerateForApplicableWorkItems(SourceProductionContext context, Compilation compilation, List workItems) + { + if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) + { + return; + } + + var items = workItems.Where(i => i.Config.Conversions.HasFlag(Conversions.MessagePack)).ToList(); + + var toWrite = items.Select(MessagePackGeneratorParams.FromWorkItem).ToList(); + + Generate(context, compilation, toWrite); + } + + public record FormatterSourceAndFilename(string FormatterFullyQualifiedName, string Filename, string SourceCode); + + private static FormatterSourceAndFilename GenerateSourceAndFilename(MessagePackGeneratorParams p) + { + var fullNamespace = p.Namespace; + + var accessor = p.WrapperAccessibility; + + var ns = string.IsNullOrEmpty(fullNamespace) ? string.Empty : $"namespace {fullNamespace};"; + + string wrapperName = Util.EscapeIfRequired(p.WrapperType.Name); + + string underlyingTypeName = p.UnderlyingType.FullName() ?? p.WrapperType.Name; + + string sb = + $$""" + {{GeneratedCodeSegments.Preamble}} + + {{ns}} + + {{accessor}} partial class {{wrapperName}}MessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<{{wrapperName}}> + { + public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrapperName}} value, global::MessagePack.MessagePackSerializerOptions options) => + writer.Write(value.Value); + + public {{wrapperName}} Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => + Deserialize(reader.{{GenerateReadMethod()}}); + + static {{wrapperName}} Deserialize({{underlyingTypeName}} value) => UnsafeDeserialize(default, value); + + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern {{wrapperName}} UnsafeDeserialize({{wrapperName}} @this, {{underlyingTypeName}} value); + } + """; + + var fn = string.IsNullOrEmpty(fullNamespace) ? "" : fullNamespace + "."; + string serializerFqn = $"{fn}{wrapperName}MessagePackFormatter"; + + var unsanitized = $"{p.WrapperType.ToDisplayString()}_messagepack.g.cs"; + string filename = Util.SanitizeToALegalFilename(unsanitized); + return new FormatterSourceAndFilename(serializerFqn, filename, sb); + } + + private static string GenerateReadMethod() + { + return "ReadInt32()"; + } +} \ No newline at end of file diff --git a/src/Vogen/GenerateCodeForMessagePackMarkers.cs b/src/Vogen/GenerateCodeForMessagePackMarkers.cs new file mode 100644 index 0000000000..5e37b6a522 --- /dev/null +++ b/src/Vogen/GenerateCodeForMessagePackMarkers.cs @@ -0,0 +1,36 @@ +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Vogen; + +internal class GenerateCodeForMessagePackMarkers +{ + public static void GenerateForMarkerClasses( + SourceProductionContext context, + Compilation compilation, + ImmutableArray conversionMarkerClasses) + { + if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) + { + return; + } + + foreach (ConversionMarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) + { + var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConverterMarkerKind.MessagePack); + + var ps = matchingMarkers.Select(ConvertToParams).ToList(); + + GenerateCodeForMessagePack.Generate(context, compilation, ps); + } + } + + private static MessagePackGeneratorParams ConvertToParams(ConversionMarkerAttributeDefinition spec) => + new( + spec.Marker!.SourceType.FullNamespace(), + spec.Marker!.VoSymbol, + spec.Marker!.UnderlyingType, + "public"); +} \ No newline at end of file diff --git a/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs b/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs index 26aace1e3f..bd37bb8375 100644 --- a/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs +++ b/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs @@ -47,7 +47,7 @@ public static string Generate(bool isWritingAsInnerClass, INamedTypeSymbol primi return code; } - public static string GenerateOuterExtensionMethod(EfCoreConverterSpec spec) + public static string GenerateOuterExtensionMethod(ConverterMarker spec) { string voTypeName = spec.VoSymbol.FullName() ?? spec.VoSymbol.Name; diff --git a/src/Vogen/ManageAttributes.cs b/src/Vogen/ManageAttributes.cs index 5ea19d54ef..87fb5c9e73 100644 --- a/src/Vogen/ManageAttributes.cs +++ b/src/Vogen/ManageAttributes.cs @@ -30,20 +30,6 @@ public static VogenConfigurationBuildResult GetDefaultConfigFromGlobalAttribute( return BuildConfigurationFromAttributes.TryBuildFromVogenDefaultsAttribute(attr); } - public static EfCoreConverterMarkerClassResults GetEfCoreConverterSpecFromAttribute(GeneratorAttributeSyntaxContext ctx) - { - INamedTypeSymbol? symbol = ctx.TargetSymbol as INamedTypeSymbol; - - var attrs = ctx.Attributes; - - if (attrs.IsDefaultOrEmpty) - { - return new EfCoreConverterMarkerClassResults(symbol, []); - } - - return new EfCoreConverterMarkerClassResults(symbol, attrs.Select(a => BuildEfCoreConverterSpecsFromAttributes.TryBuild(a, symbol))); - } - /// /// Gets global default configuration from any global (assembly) attribute. /// This is used by the analyzer. diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs index b09c8d86fe..dfd37709de 100644 --- a/src/Vogen/ValueObjectGenerator.cs +++ b/src/Vogen/ValueObjectGenerator.cs @@ -27,9 +27,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var targetsAndConfig = collectedVos.Combine(found.GlobalConfig.Collect()); - var targetsConfigAndEfCoreSpecs = targetsAndConfig.Combine(found.EfCoreConverterSpecs.Collect()); + var targetsConfigAndConversionMarkers = targetsAndConfig.Combine(found.ConverterMarkerClasses.Collect()); - var compilationAndValues = context.CompilationProvider.Combine(targetsConfigAndEfCoreSpecs); + var compilationAndValues = context.CompilationProvider.Combine(targetsConfigAndConversionMarkers); var everything = compilationAndValues.Combine(knownSymbols); @@ -69,26 +69,25 @@ private static Found GetTargets(SyntaxValueProvider syntaxProvider) transform: (ctx, _) => ManageAttributes.GetDefaultConfigFromGlobalAttribute(ctx)) .Where(static m => m is not null)!; - IncrementalValuesProvider efCoreConverterSpecs = syntaxProvider.ForAttributeWithMetadataName( - "Vogen.EfCoreConverterAttribute`1", - predicate: (node, _) => node is ClassDeclarationSyntax, - transform: (ctx, _) => ManageAttributes.GetEfCoreConverterSpecFromAttribute(ctx)) + IncrementalValuesProvider converterMarkerClasses = syntaxProvider.CreateSyntaxProvider( + predicate: (node, _) => ConversionMarkers.IsTarget(node), + transform: (ctx, _) => ConversionMarkers.GetConversionMarkerClassDefinitionFromAttribute(ctx)) .Where(static m => m is not null)!; - return new Found(targets, globalConfig, efCoreConverterSpecs); + return new Found(targets, globalConfig, converterMarkerClasses); } record struct Found( IncrementalValuesProvider Vos, IncrementalValuesProvider GlobalConfig, - IncrementalValuesProvider EfCoreConverterSpecs); + IncrementalValuesProvider ConverterMarkerClasses); private static void Execute( Compilation compilation, VogenKnownSymbols vogenKnownSymbols, ImmutableArray targets, ImmutableArray globalConfigBuildResult, - ImmutableArray efCoreConverterSpecs, + ImmutableArray conversionMarkerClassDefinitions, SourceProductionContext spc) { var csharpCompilation = compilation as CSharpCompilation; @@ -99,7 +98,7 @@ private static void Execute( internalDiags.RecordTargets(targets); - var efSpecErrors = efCoreConverterSpecs.SelectMany(x => x.Diagnostics); + var efSpecErrors = conversionMarkerClassDefinitions.SelectMany(x => x.Diagnostics); foreach (var diagnostic in efSpecErrors) { @@ -125,7 +124,12 @@ private static void Execute( GenerateCodeForOpenApiSchemaCustomization.WriteIfNeeded(globalConfig, spc, workItems, vogenKnownSymbols, compilation); - GenerateCodeForEfCoreSpecs.WriteIfNeeded(spc, compilation, efCoreConverterSpecs); + GenerateCodeForConversionMarkers.Generate(spc, compilation, conversionMarkerClassDefinitions); + + // the user can specify to create the MessagePack generated code as an attribute + // or as marker in another project. + GenerateCodeForMessagePack.GenerateForApplicableWorkItems(spc, compilation, workItems); + GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, conversionMarkerClassDefinitions); GenerateCodeForBsonSerializers.WriteIfNeeded(spc, compilation, workItems); diff --git a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs index bf64d7a524..385402b7ba 100644 --- a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs +++ b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs @@ -9,6 +9,52 @@ namespace SnapshotTests.GeneralStuff; public class GeneralTests { + [Fact] + public async Task Generates_messagepack() + { + var source = + $$""" + + using System; + using Vogen; + + namespace Whatever; + + [ValueObject(conversions: Conversions.MessagePack)] + public partial struct MyId; + """; + + await new SnapshotRunner() + .WithSource(source) + .WithPackage(new NuGetPackage("MessagePack", "2.5.187", "lib/netstandard2.0" )) + .RunOn(TargetFramework.Net8_0); + } + + [Fact] + public async Task Generates_messagepack_markers() + { + var source = + $$""" + + using System; + using Vogen; + + namespace Whatever; + + [ValueObject(conversions: Conversions.None)] + public partial struct MyId; + + [MessagePack] + public partial class MyMarkers; + + """; + + await new SnapshotRunner() + .WithSource(source) + .WithPackage(new NuGetPackage("MessagePack", "2.5.187", "lib/netstandard2.0" )) + .RunOn(TargetFramework.Net8_0); + } + [Fact] public async Task Skips_ToString_methods_that_implement_an_interface() { diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt new file mode 100644 index 0000000000..5f282702bb --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/Testbench/EfCoreTest/EfCoreScenario.cs b/tests/Testbench/EfCoreTest/EfCoreScenario.cs deleted file mode 100644 index 6e4a949923..0000000000 --- a/tests/Testbench/EfCoreTest/EfCoreScenario.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Query.Internal; -// ReSharper disable UnusedVariable - -namespace Vogen.EfCoreTest; - -public static class EfCoreScenario -{ - public static void Run() - { - using var context = new MyContext(); - //context.Database.Migrate(); - - AddAndSaveItems(amount: 10); - AddAndSaveItems(amount: 10); - - PrintItems(); - - FilterItems(); - - return; - - static void AddAndSaveItems(int amount) - { - using var context = new MyContext(); - - for (int i = 0; i < amount; i++) - { - var entity = new EmployeeEntity - { - Name = Name.From("Fred #" + i), - Age = Age.From(42 + i), - Department = Department.From("Quarry"), - HireDate = HireDate.From(new DateOnly(1066, 12, 13)) - }; - - context.Entities.Add(entity); - } - - context.SaveChanges(); - } - - static void PrintItems() - { - using var ctx = new MyContext(); - - var entities = ctx.Entities.ToList(); - Console.WriteLine(string.Join(Environment.NewLine, entities.Select(e => $"ID: {e.Id.Value}, Name: {e.Name}, Age: {e.Age}"))); - } - - static void FilterItems() - { - Console.WriteLine(); - Console.WriteLine("FILTERING ITEMS..."); - using var ctx = new MyContext(); - - // int age = 50; - // var entities = from e in ctx.Entities where e != null && e.Age == age select e; - // var entities2 = ctx.Entities.Where(e => e != null && e.Age == age); - - DbSet step1 = ctx.Entities; - //IQueryable step2 = step1.Take(4); - // var step3 = step1.Where(e => e.Age == age); - - - -// Console.WriteLine(string.Join(Environment.NewLine, entities.Select(e => $"ID: {e.Id.Value}, Name: {e.Name}, Age: {e.Age}"))); - - } - } - -} diff --git a/tests/Testbench/EfCoreTest/TypesAndModels.cs b/tests/Testbench/EfCoreTest/TypesAndModels.cs deleted file mode 100644 index 831f68cde2..0000000000 --- a/tests/Testbench/EfCoreTest/TypesAndModels.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; -using Microsoft.EntityFrameworkCore.ValueGeneration; - -namespace Vogen.EfCoreTest; - -public class EmployeeEntity -{ - public Id Id { get; set; } = null!; // must be null in order for EF core to generate a value - public required Name Name { get; set; } = Name.NotSet; - public required Age Age { get; set; } - - public required Department Department { get; set; } - - public required HireDate HireDate { get; set; } -} - -[ValueObject] -public partial class Id; - -[ValueObject] -[Instance("NotSet", "[NOT_SET]")] -public partial class Name; - -[ValueObject] -public readonly partial struct Age; - -[ValueObject] -public readonly partial record struct Department; - -[ValueObject] -public partial record class HireDate; - - -internal class MyContext : Microsoft.EntityFrameworkCore.DbContext -{ - public DbSet Entities { get; set; } = default!; - - // you can use this method explicitly when creating your entities, or use SomeIdValueGenerator as shown below - // public int GetNextMyEntityId() - // { - // var maxLocalId = SomeEntities.Local.Any() ? SomeEntities.Local.Max(e => e.Id.Value) : 0; - // var maxSavedId = SomeEntities.Any() ? SomeEntities.Max(e => e.Id.Value) : 0; - // return Math.Max(maxLocalId, maxSavedId) + 1; - // } - - protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) - { - base.ConfigureConventions(configurationBuilder); - - // There are two ways of registering these, you can call the generated extension method here, - // or register the converters individually, like below in `OnModelCreating`. - // configurationBuilder.RegisterAllInVogenEfCoreConverters2(); - // configurationBuilder.RegisterAllInVogenEfCoreConverters2(); - } - - protected override void OnModelCreating(ModelBuilder builder) - { - builder.Entity(b => - { - b.HasKey(x => x.Id); - b.Property(e => e.Id).HasValueGenerator(); - - // There are two ways of registering these, you can do them inline here, - // or with the `RegisterAllIn[xxx]` like above in `ConfigureConventions` - - b.Property(e => e.Id).HasVogenConversion(); - b.Property(e => e.Age).HasVogenConversion(); - b.Property(e => e.Name).HasVogenConversion(); - b.Property(e => e.Department).HasVogenConversion(); - b.Property(e => e.HireDate).HasVogenConversion(); - }); - } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - -optionsBuilder.UseSqlite("Data Source=SomeDB.db"); - //optionsBuilder.UseInMemoryDatabase("SomeDB"); - } -} - -internal class SomeIdValueGenerator : ValueGenerator -{ - public override Id Next(EntityEntry entry) - { - var entities = ((MyContext)entry.Context).Entities; - - var next = Math.Max(MaxFrom(entities.Local), MaxFrom(entities)) + 1; - - return Id.From(next); - - static int MaxFrom(IEnumerable es) - { - return es.Any() ? es.Max(e => e.Id.Value) : 0; - } - } - - public override bool GeneratesTemporaryValues => false; -} diff --git a/tests/Testbench/Migrations/20241021092427_Initial.Designer.cs b/tests/Testbench/Migrations/20241021092427_Initial.Designer.cs deleted file mode 100644 index b9aace2dc3..0000000000 --- a/tests/Testbench/Migrations/20241021092427_Initial.Designer.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Vogen.EfCoreTest; - -#nullable disable - -namespace Testbench.Migrations -{ - [DbContext(typeof(MyContext))] - [Migration("20241021092427_Initial")] - partial class Initial - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); - - modelBuilder.Entity("Vogen.EfCoreTest.EmployeeEntity", b => - { - b.Property("Id") - .HasColumnType("INTEGER"); - - b.Property("Age") - .HasColumnType("INTEGER"); - - b.Property("Department") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("HireDate") - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Entities"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/tests/Testbench/Migrations/20241021092427_Initial.cs b/tests/Testbench/Migrations/20241021092427_Initial.cs deleted file mode 100644 index 3683e2639f..0000000000 --- a/tests/Testbench/Migrations/20241021092427_Initial.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Testbench.Migrations -{ - /// - public partial class Initial : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Entities", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false), - Name = table.Column(type: "TEXT", nullable: false), - Age = table.Column(type: "INTEGER", nullable: false), - Department = table.Column(type: "TEXT", nullable: false), - HireDate = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Entities", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Entities"); - } - } -} diff --git a/tests/Testbench/Migrations/MyContextModelSnapshot.cs b/tests/Testbench/Migrations/MyContextModelSnapshot.cs deleted file mode 100644 index bfe2852423..0000000000 --- a/tests/Testbench/Migrations/MyContextModelSnapshot.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Vogen.EfCoreTest; - -#nullable disable - -namespace Testbench.Migrations -{ - [DbContext(typeof(MyContext))] - partial class MyContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.10"); - - modelBuilder.Entity("Vogen.EfCoreTest.EmployeeEntity", b => - { - b.Property("Id") - .HasColumnType("INTEGER"); - - b.Property("Age") - .HasColumnType("INTEGER"); - - b.Property("Department") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("HireDate") - .HasColumnType("TEXT"); - - b.Property("Name") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Entities"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/tests/Testbench/Program.cs b/tests/Testbench/Program.cs index 84c3859f25..ce801ee440 100644 --- a/tests/Testbench/Program.cs +++ b/tests/Testbench/Program.cs @@ -4,87 +4,22 @@ using System.IO; using System.Linq; using System.Xml.Serialization; +using MessagePack; using Vogen; // ReSharper disable UnusedVariable -[assembly: VogenDefaults( - openApiSchemaCustomizations: OpenApiSchemaCustomizations.GenerateSwashbuckleSchemaFilter | - OpenApiSchemaCustomizations.GenerateSwashbuckleMappingExtensionMethod, - staticAbstractsGeneration: StaticAbstractsGeneration.MostCommon | StaticAbstractsGeneration.InstanceMethodsAndProperties, - conversions: Conversions.EfCoreValueConverter)] - namespace Testbench; -[ValueObject(conversions: Conversions.XmlSerializable)] -public partial class MyShort; - -[ValueObject(conversions: Conversions.XmlSerializable, primitiveEqualityGeneration: PrimitiveEqualityGeneration.GenerateOperatorsAndMethods)] +[ValueObject(conversions: Conversions.MessagePack)] public partial class MyInt; -[ValueObject] -public partial struct MyDateOnly; - -[ValueObject] -public partial struct MyDateTime; - -[ValueObject] -public partial struct MyDateTimeOffset; - -[ValueObject] -public partial struct MyByte; - -[ValueObject] -public partial struct MyLong; - -[Serializable] -public class C -{ - public required MyInt MyInt { get; set; } - public required MyShort MyShort { get; set; } -} +[MessagePack()] +public partial class MyMarkers; public static class Program { public static void Main() { - MyInt i1 = MyInt.From(100); - MyInt i2 = MyInt.From(200); - bool smaller = i1.CompareTo(i2) < 0; - bool smaller2 = i1 == 100; - - C c = new() - { - MyInt = MyInt.From(42), - MyShort = MyShort.From(123) - }; - - - - // C2 c = new() - // { - // MyInt = 42, - // MyShort = 111, - // MyShortXml = 222, - // }; - - -// Serialize 'c' to XML - XmlSerializer serializer = new XmlSerializer(typeof(C)); - using StringWriter textWriter = new StringWriter(); - - serializer.Serialize(textWriter, c); - string xmlString = textWriter.ToString(); - Console.WriteLine("Serialized XML:\n" + xmlString); - - -// Deserialize XML back to a 'C' object - using (StringReader textReader = new StringReader(xmlString)) - { - C deserializedC = (C) serializer.Deserialize(textReader)!; - Console.WriteLine("Deserialized Object:"); - Console.WriteLine("MyInt: " + deserializedC.MyInt); - Console.WriteLine("MyShort: " + deserializedC.MyShort); - } } } \ No newline at end of file diff --git a/tests/Testbench/Testbench.csproj b/tests/Testbench/Testbench.csproj index 14b48b2842..f54f8f6b38 100644 --- a/tests/Testbench/Testbench.csproj +++ b/tests/Testbench/Testbench.csproj @@ -19,6 +19,7 @@ bin\Debug\Testbench.xml + all runtime; build; native; contentfiles; analyzers; buildtransitive From 35fcccecf790d4cc5f6c1bb65eb7f6730a06decd Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Tue, 12 Nov 2024 07:06:40 +0000 Subject: [PATCH 02/10] Tidy up --- Directory.Build.props | 2 +- src/Vogen/AnalyzerReleases.Shipped.md | 3 +- src/Vogen/AnalyzerReleases.Unshipped.md | 3 +- ...onverterMarkerDefinitionsFromAttributes.cs | 69 -------- src/Vogen/ConversionMarker.cs | 16 ++ .../ConversionMarkerAttributeDefinition.cs | 35 ---- src/Vogen/ConversionMarkerClassDefinition.cs | 25 --- src/Vogen/ConversionMarkers.cs | 110 ++++++++++-- src/Vogen/ConverterMarker.cs | 15 -- src/Vogen/Diagnostics/DiagnosticsCatalogue.cs | 32 ++-- src/Vogen/Diagnostics/RuleIdentifiers.cs | 5 +- src/Vogen/Extensions/IEnumerableExtensions.cs | 20 +++ ...arkers.cs => GenerateCodeEfCoreMarkers.cs} | 50 +++--- src/Vogen/GenerateCodeForMessagePack.cs | 129 +++++++++----- .../GenerateCodeForMessagePackMarkers.cs | 24 +-- .../Conversions/GenerateEfCoreTypes.cs | 29 ++-- src/Vogen/MarkerAttribute2.cs | 49 ++++++ src/Vogen/MarkerAttributeDefinition.cs | 36 ++++ src/Vogen/MarkerClassDefinition.cs | 25 +++ src/Vogen/Util.cs | 16 ++ src/Vogen/ValueObjectGenerator.cs | 16 +- tests/AnalyzerTests/EfCoreTests.cs | 78 --------- tests/AnalyzerTests/MarkerClassTests.cs | 164 ++++++++++++++++++ .../GeneralStuff/GeneralTests.cs | 5 +- tests/Testbench/MyInt.cs | 6 + tests/Testbench/MyString.cs | 6 + tests/Testbench/Program.cs | 8 +- 27 files changed, 598 insertions(+), 378 deletions(-) create mode 100644 src/Vogen/ConversionMarker.cs delete mode 100644 src/Vogen/ConversionMarkerAttributeDefinition.cs delete mode 100644 src/Vogen/ConversionMarkerClassDefinition.cs delete mode 100644 src/Vogen/ConverterMarker.cs rename src/Vogen/{GenerateCodeForConversionMarkers.cs => GenerateCodeEfCoreMarkers.cs} (63%) create mode 100644 src/Vogen/MarkerAttribute2.cs create mode 100644 src/Vogen/MarkerAttributeDefinition.cs create mode 100644 src/Vogen/MarkerClassDefinition.cs delete mode 100644 tests/AnalyzerTests/EfCoreTests.cs create mode 100644 tests/AnalyzerTests/MarkerClassTests.cs create mode 100644 tests/Testbench/MyInt.cs create mode 100644 tests/Testbench/MyString.cs diff --git a/Directory.Build.props b/Directory.Build.props index 20f2028616..838b3f0684 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -3,7 +3,7 @@ preview strict true - $(NoWarn);CS1701;CS1702;CS1591;CA1014;CS9057;CA2255 + $(NoWarn);CS1701;CS1702;CS1591;CA1014;CS9057;CA2255;NU1904 true false latest diff --git a/src/Vogen/AnalyzerReleases.Shipped.md b/src/Vogen/AnalyzerReleases.Shipped.md index cb6ad4fe00..1e4acb9532 100644 --- a/src/Vogen/AnalyzerReleases.Shipped.md +++ b/src/Vogen/AnalyzerReleases.Shipped.md @@ -64,4 +64,5 @@ VOG032 | Usage | Warning | DoNotThrowFromUserCodeAnalyzer Rule ID | Category | Severity | Notes --------|----------|----------|------- VOG033 | Usage | Info | UseReadonlyStructInsteadOfStructAnalyzer -VOG034 | Usage | Error | DoNotCompareWithPrimitivesInEfCoreAnalyzer \ No newline at end of file +VOG034 | Usage | Error | DoNotCompareWithPrimitivesInEfCoreAnalyzer + diff --git a/src/Vogen/AnalyzerReleases.Unshipped.md b/src/Vogen/AnalyzerReleases.Unshipped.md index bc08846474..088fcce3c8 100644 --- a/src/Vogen/AnalyzerReleases.Unshipped.md +++ b/src/Vogen/AnalyzerReleases.Unshipped.md @@ -1,9 +1,8 @@ ; Unshipped analyzer release ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md + ### New Rules Rule ID | Category | Severity | Notes --------|----------|----------|------- - - diff --git a/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs b/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs index c9fcdec82e..b3efe1767e 100644 --- a/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs +++ b/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs @@ -10,75 +10,6 @@ namespace Vogen; internal static class BuildConverterMarkerDefinitionsFromAttributes { - public static ConversionMarkerAttributeDefinition? TryBuild(AttributeData att, in INamedTypeSymbol? markerClassSymbol) - { - ImmutableArray args = att.ConstructorArguments; - var hasErroredAttributes = args.Any(a => a.Kind == TypedConstantKind.Error); - if (hasErroredAttributes) - { - // skip further generator execution and let compiler generate the errors - return null; - } - - if (att.AttributeClass == null) - { - return null; - } - - ImmutableArray argumentSymbols = att.AttributeClass.TypeArguments; - - if (argumentSymbols.Length != 1) - { - return null; - } - - var voSymbol = argumentSymbols[0] as INamedTypeSymbol; - - if (voSymbol is null) - { - return null; - } - - if (!VoFilter.IsTarget(voSymbol)) - { - return ConversionMarkerAttributeDefinition.Error(ConverterMarkerKind.EFCore, DiagnosticsCatalogue.EfCoreTargetMustBeAVo(markerClassSymbol!, voSymbol)); - } - - List attrs = VoFilter.TryGetValueObjectAttributes(voSymbol).ToList(); - - if(attrs.Count != 1) return null; - - AttributeData a = attrs[0]; - - VogenConfigurationBuildResult config = BuildConfigurationFromAttributes.TryBuildFromValueObjectAttribute(a); - - if(config.HasDiagnostics) return null; - - VogenConfiguration c = config.ResultingConfiguration!; - - var underlyingType = c.UnderlyingType ?? ResolveUnderlyingType(voSymbol); - - if (underlyingType is null) - { - return ConversionMarkerAttributeDefinition.Error(ConverterMarkerKind.EFCore, DiagnosticsCatalogue.VoMustExplicitlySpecifyPrimitiveToBeAnEfCoreTarget(voSymbol)); - } - - return ConversionMarkerAttributeDefinition.Ok(ConverterMarkerKind.EFCore, voSymbol, underlyingType, markerClassSymbol!); - } - - private static INamedTypeSymbol? ResolveUnderlyingType(INamedTypeSymbol method) - { - ImmutableArray ms = method.GetMembers("Value"); - - if (ms.Length == 0) - { - return null; - } - - IPropertySymbol? prop = ms[0] as IPropertySymbol; - - return (INamedTypeSymbol)prop!.Type; - } } \ No newline at end of file diff --git a/src/Vogen/ConversionMarker.cs b/src/Vogen/ConversionMarker.cs new file mode 100644 index 0000000000..4b6b75e178 --- /dev/null +++ b/src/Vogen/ConversionMarker.cs @@ -0,0 +1,16 @@ +using Microsoft.CodeAnalysis; + +namespace Vogen; + +/// +/// Represents an instance of a marker attribute, e.g. `EfCoreConverterAttribute` or a `MemoryPackageConverterAttribute`, and its +/// containing marker class. +/// +/// The symbol for the value object being referenced. In effect, the generic value of the attribute. +/// The symbol for the underlying type that is represented by the value object. +/// The symbol for the marker class that has the marker attribute(s). +internal record ConversionMarker( + ConversionMarkerKind Kind, + INamedTypeSymbol VoSymbol, + INamedTypeSymbol UnderlyingTypeSymbol, + INamedTypeSymbol MarkerClassSymbol); \ No newline at end of file diff --git a/src/Vogen/ConversionMarkerAttributeDefinition.cs b/src/Vogen/ConversionMarkerAttributeDefinition.cs deleted file mode 100644 index 794d25c8b0..0000000000 --- a/src/Vogen/ConversionMarkerAttributeDefinition.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace Vogen; - -public enum ConverterMarkerKind -{ - EFCore, - MessagePack, -} - -/// -/// Represents the *definition* of a 'marker attribute, e.g. an 'EFCore marker' or 'memory pack marker' - that is, a partial class decorated with an -/// attribute such as `EfCoreConverter`, or 'MemoryPackConverter'. This is the singular item; a particular attribute on the method, -/// and contains the symbol for the value object being referenced, a symbol for the underlying type of the value object, -/// and a symbol for the method containing the attribute. -/// -internal sealed class ConversionMarkerAttributeDefinition -{ - private ConversionMarkerAttributeDefinition(ConverterMarker? marker, IEnumerable diagnostics) - { - Marker = marker; - Diagnostics = diagnostics.ToList(); - } - - public ConverterMarker? Marker { get; } - - public List Diagnostics { get; } - - public static ConversionMarkerAttributeDefinition Error(ConverterMarkerKind efCore, Diagnostic diag) => new(null, [diag]); - - public static ConversionMarkerAttributeDefinition Ok(ConverterMarkerKind kind, INamedTypeSymbol voSymbol, INamedTypeSymbol underlyingTypeSymbol, INamedTypeSymbol sourceSymbol) => - new(marker: new ConverterMarker(kind, voSymbol, underlyingTypeSymbol, sourceSymbol), diagnostics: []); -} \ No newline at end of file diff --git a/src/Vogen/ConversionMarkerClassDefinition.cs b/src/Vogen/ConversionMarkerClassDefinition.cs deleted file mode 100644 index f614f6ab7e..0000000000 --- a/src/Vogen/ConversionMarkerClassDefinition.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.CodeAnalysis; - -namespace Vogen; - -/// -/// Represents a collection of EFCore converter marker definitions (`EfCoreConverter<>`) that are all associated with the same type symbol -/// (that is, the type containing the `EfCoreConverter` attributes). -/// -internal sealed class ConversionMarkerClassDefinition -{ - public INamedTypeSymbol? MarkerClassSymbol { get; } - - public ConversionMarkerClassDefinition(INamedTypeSymbol? markerClassSymbol, IEnumerable markers) - { - MarkerClassSymbol = markerClassSymbol; - Results = markers.Where(r => r is not null)!; - } - - private IEnumerable Results { get; } - - public IEnumerable Diagnostics => Results.SelectMany(r => r.Diagnostics); - public IEnumerable AttributeDefinitions => Results; -} \ No newline at end of file diff --git a/src/Vogen/ConversionMarkers.cs b/src/Vogen/ConversionMarkers.cs index 0870a0a928..fcf7fb13ff 100644 --- a/src/Vogen/ConversionMarkers.cs +++ b/src/Vogen/ConversionMarkers.cs @@ -1,31 +1,35 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Vogen.Diagnostics; namespace Vogen; internal static class ConversionMarkers { + private static readonly Dictionary _knownMarkerAttributes = new() + { + { "EfCoreConverterAttribute`1", ConversionMarkerKind.EFCore }, + { "MessagePackAttribute`1", ConversionMarkerKind.MessagePack } + }; + /// - /// Tries to get any `ValueObject` attributes specified on the provided symbol. - /// It might return more than one, because the user might have typed more than one. - /// Even though having more than one is not valid, it's still possible for it to exist, - /// so we return what is found and let the caller decide what to do. + /// Tries to get any 'Market Object' attributes on a class. /// - /// + /// /// - public static IEnumerable TryGetMarkerAttributes(INamedTypeSymbol voSymbolInformation) + public static IEnumerable TryGetMarkerAttributes(INamedTypeSymbol markerClass) { - var attrs = voSymbolInformation.GetAttributes(); + var attrs = markerClass.GetAttributes(); return attrs.Where( - a => a.AttributeClass?.MetadataName == "EfCoreConverterAttribute`1" - || a.AttributeClass?.MetadataName == "MessagePackAttribute`1"); + a => _knownMarkerAttributes.ContainsKey(a.AttributeClass?.MetadataName ?? "")); } - public static ConversionMarkerClassDefinition? GetConversionMarkerClassDefinitionFromAttribute(GeneratorSyntaxContext context) + public static MarkerClassDefinition? GetConversionMarkerClassDefinitionFromAttribute(GeneratorSyntaxContext context) { // var voSyntaxInformation = (TypeDeclarationSyntax) context.Node; @@ -33,17 +37,93 @@ public static IEnumerable TryGetMarkerAttributes(INamedTypeSymbol ISymbol declaredSymbol = semanticModel.GetDeclaredSymbol(context.Node)!; - var voSymbolInformation = (INamedTypeSymbol) declaredSymbol; + var markerClassSymbol = (INamedTypeSymbol) declaredSymbol; - var attributeData = TryGetMarkerAttributes(voSymbolInformation).ToImmutableArray(); + ImmutableArray attributeData = TryGetMarkerAttributes(markerClassSymbol).ToImmutableArray(); if (attributeData.Length == 0) return null; - return new ConversionMarkerClassDefinition( - voSymbolInformation, - attributeData.Select(a => BuildConverterMarkerDefinitionsFromAttributes.TryBuild(a, voSymbolInformation))); + return new MarkerClassDefinition( + markerClassSymbol, + attributeData.Select(a => TryBuild(a, markerClassSymbol))); } public static bool IsTarget(SyntaxNode node) => node is TypeDeclarationSyntax { AttributeLists.Count: > 0 }; + + + public static MarkerAttributeDefinition? TryBuild(AttributeData markerAtt, in INamedTypeSymbol? markerClassSymbol) + { + ImmutableArray args = markerAtt.ConstructorArguments; + + var hasErroredAttributes = args.Any(a => a.Kind == TypedConstantKind.Error); + + if (hasErroredAttributes) + { + // skip further generator execution and let compiler generate the errors + return null; + } + + if (markerAtt.AttributeClass == null) + { + return null; + } + + var voSymbol = markerAtt.AttributeClass.TypeArguments.SingleOrDefaultIfMultiple() as INamedTypeSymbol; + + if (voSymbol is null) + { + return null; + } + + ConversionMarkerKind markerKind = ResolveMarkerKind(markerAtt); + + if(markerKind is ConversionMarkerKind.Unrecognized) return null; + + if (!VoFilter.IsTarget(voSymbol)) + { +// return ConversionMarkerAttributeDefinition.Error(markerKind, DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol)); + return MarkerAttributeDefinition.Error(markerKind, DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol)); + } + + List voAttributes = VoFilter.TryGetValueObjectAttributes(voSymbol).ToList(); + + if(voAttributes.Count != 1) return null; + + AttributeData voAttribute = voAttributes[0]; + + VogenConfigurationBuildResult config = BuildConfigurationFromAttributes.TryBuildFromValueObjectAttribute(voAttribute); + + if(config.HasDiagnostics) return null; + + VogenConfiguration c = config.ResultingConfiguration!; + + var underlyingType = c.UnderlyingType ?? ResolveUnderlyingType(voSymbol); + + if (underlyingType is null) + { + return MarkerAttributeDefinition.Error( + markerKind, + DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol, markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation())); + } + + return MarkerAttributeDefinition.Ok(markerKind, voSymbol, underlyingType, markerClassSymbol!); + } + + private static ConversionMarkerKind ResolveMarkerKind(AttributeData att) => + _knownMarkerAttributes.TryGetValue(att.AttributeClass?.MetadataName ?? "", out var kind) ? kind : ConversionMarkerKind.Unrecognized; + + private static INamedTypeSymbol? ResolveUnderlyingType(INamedTypeSymbol method) + { + ImmutableArray ms = method.GetMembers("Value"); + + if (ms.Length == 0) + { + return null; + } + + IPropertySymbol? prop = ms[0] as IPropertySymbol; + + return (INamedTypeSymbol)prop!.Type; + } } \ No newline at end of file diff --git a/src/Vogen/ConverterMarker.cs b/src/Vogen/ConverterMarker.cs deleted file mode 100644 index 9a92e1c2bb..0000000000 --- a/src/Vogen/ConverterMarker.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace Vogen; - -/// -/// Represents an instance of a marker class attribute, e.g. `EfCoreConverterAttribute` or a `MemoryPackageConverterAttribute`. -/// -/// The symbol for the value object being referenced. In effect, the generic value of the attribute. -/// The symbol for the underlying type that is represented by the value object. -/// The symbol for the method that contains the `EfCoreConverter` attribute(s). -internal record ConverterMarker( - ConverterMarkerKind Kind, - INamedTypeSymbol VoSymbol, - INamedTypeSymbol UnderlyingType, - INamedTypeSymbol SourceType); \ No newline at end of file diff --git a/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs b/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs index 9e456bc07f..b8fc063252 100644 --- a/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs +++ b/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs @@ -118,15 +118,15 @@ internal static class DiagnosticsCatalogue "Invalid custom exception", "{0} must have at least 1 public constructor with 1 parameter of type System.String"); - private static readonly DiagnosticDescriptor _efCoreTargetMustExplicitlySpecifyItsPrimitive = CreateDescriptor( - RuleIdentifiers.EfCoreTargetMustExplicitlySpecifyItsPrimitive, - "Value objects must explicitly specify the primitive type", - "Type '{0}' must explicitly specify the primitive type that it wraps in order for its EFCore converter to be generated"); + private static readonly DiagnosticDescriptor _voReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive = CreateDescriptor( + RuleIdentifiers.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive, + "Value objects that are referenced in a conversion marker attribute must explicitly specify the primitive type", + "Marker class '{0}' specifies a target value object '{1}', but that type does not explicitly specify the primitive type that it wraps"); - private static readonly DiagnosticDescriptor _efCoreTargetMustBeAVo = CreateDescriptor( - RuleIdentifiers.EfCoreTargetMustBeAVo, - "EFCore target must be a value object", - "Type '{0}' specifies a target value object of {1} but it is not a value object"); + private static readonly DiagnosticDescriptor _typesReferencedInAConversionMarkerMustBeaValueObjects = CreateDescriptor( + RuleIdentifiers.TypesReferencedInAConversionMarkerMustBeaValueObjects, + "Types referenced in conversion markers by be value objects", + "Marker class '{0}' specifies a target value object '{1}', but that is not a value object"); public static Diagnostic TypeCannotBeNested(INamedTypeSymbol typeModel, INamedTypeSymbol container) => Create(_typeCannotBeNested, typeModel.Locations, typeModel.Name, container.Name); @@ -191,11 +191,17 @@ public static Diagnostic CustomExceptionMustDeriveFromException(INamedTypeSymbol public static Diagnostic CustomExceptionMustHaveValidConstructor(INamedTypeSymbol symbol) => Create(_customExceptionMustHaveValidConstructor, symbol.Locations, symbol.Name); - public static Diagnostic VoMustExplicitlySpecifyPrimitiveToBeAnEfCoreTarget(INamedTypeSymbol symbol) => - Create(_efCoreTargetMustExplicitlySpecifyItsPrimitive, symbol.Locations, symbol.Name); - - public static Diagnostic EfCoreTargetMustBeAVo(INamedTypeSymbol markerClassSymbol, INamedTypeSymbol voSymbol) => - Create(_efCoreTargetMustBeAVo, voSymbol.Locations, markerClassSymbol.Name, voSymbol.Name); + public static Diagnostic VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(INamedTypeSymbol voSymbol, + INamedTypeSymbol markerClassSymbol, + Location? location) => + Create( + _voReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive, + location, + voSymbol.Name, + markerClassSymbol.Name); + + public static Diagnostic TypesReferencedInAConversionMarkerMustBeaValueObjects(INamedTypeSymbol markerClassSymbol, INamedTypeSymbol voSymbol) => + Create(_typesReferencedInAConversionMarkerMustBeaValueObjects, voSymbol.Locations, markerClassSymbol.Name, voSymbol.Name); private static DiagnosticDescriptor CreateDescriptor(string code, string title, string messageFormat, DiagnosticSeverity severity = DiagnosticSeverity.Error) { diff --git a/src/Vogen/Diagnostics/RuleIdentifiers.cs b/src/Vogen/Diagnostics/RuleIdentifiers.cs index 03ce804754..709e8f02e0 100644 --- a/src/Vogen/Diagnostics/RuleIdentifiers.cs +++ b/src/Vogen/Diagnostics/RuleIdentifiers.cs @@ -37,9 +37,10 @@ public static class RuleIdentifiers public const string IncorrectUseOfInstanceField = "VOG027"; public const string IncorrectUseOfNormalizeInputMethod = "VOG028"; public const string ExplicitlySpecifyTypeInValueObjectAttribute = "VOG029"; - public const string EfCoreTargetMustExplicitlySpecifyItsPrimitive = "VOG030"; - public const string EfCoreTargetMustBeAVo = "VOG031"; + //public const string EfCoreTargetMustExplicitlySpecifyItsPrimitive = "VOG030"; + public const string TypesReferencedInAConversionMarkerMustBeaValueObjects = "VOG031"; public const string DoNotThrowFromUserCode = "VOG032"; public const string UseReadonlyStructInsteadOfStruct = "VOG033"; public const string DoNotCompareWithPrimitivesInEfCore = "VOG034"; + public const string VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive = "VOG035"; } \ No newline at end of file diff --git a/src/Vogen/Extensions/IEnumerableExtensions.cs b/src/Vogen/Extensions/IEnumerableExtensions.cs index c1a18758fb..060f2795e4 100644 --- a/src/Vogen/Extensions/IEnumerableExtensions.cs +++ b/src/Vogen/Extensions/IEnumerableExtensions.cs @@ -12,6 +12,26 @@ namespace Analyzer.Utilities.Extensions { internal static class IEnumerableExtensions { + public static T? SingleOrDefaultIfMultiple(this IEnumerable source) + { + using var iterator = source.GetEnumerator(); + try + { + if (iterator.MoveNext()) + { + var result = iterator.Current; + if (!iterator.MoveNext()) + return result; + } + } + finally + { + iterator.Dispose(); + } + + return default!; + } + public static IEnumerable Concat(this IEnumerable source, T value) { if (source == null) diff --git a/src/Vogen/GenerateCodeForConversionMarkers.cs b/src/Vogen/GenerateCodeEfCoreMarkers.cs similarity index 63% rename from src/Vogen/GenerateCodeForConversionMarkers.cs rename to src/Vogen/GenerateCodeEfCoreMarkers.cs index 6465ca1675..12ff999ef7 100644 --- a/src/Vogen/GenerateCodeForConversionMarkers.cs +++ b/src/Vogen/GenerateCodeEfCoreMarkers.cs @@ -9,50 +9,45 @@ namespace Vogen; -internal class GenerateCodeForConversionMarkers +internal class GenerateCodeEfCoreMarkers { - public static void Generate(SourceProductionContext context, Compilation compilation, ImmutableArray conversionMarkerClasses) + public static void Generate(SourceProductionContext context, Compilation compilation, ImmutableArray markerClasses) { if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) { return; } - foreach (ConversionMarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) + foreach (MarkerClassDefinition? eachMarkerClass in markerClasses) { - var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConverterMarkerKind.EFCore); + var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConversionMarkerKind.EFCore); - WriteEncompassingExtensionMethod( - eachMarkerClass.MarkerClassSymbol, - matchingMarkers, context); + StoreExtensionMethodToRegisterAllInMarkerClass(eachMarkerClass.MarkerClassSymbol, matchingMarkers, context); - foreach (ConversionMarkerAttributeDefinition? eachAttributeInMarkerClass in matchingMarkers) + foreach (MarkerAttributeDefinition? eachAttributeInMarkerClass in matchingMarkers) { - WriteEachIfNeeded(context, eachAttributeInMarkerClass); + WriteEachIfNeeded(context, eachAttributeInMarkerClass.Marker); } } } - private static void WriteEachIfNeeded(SourceProductionContext context, ConversionMarkerAttributeDefinition specResult) + private static void WriteEachIfNeeded(SourceProductionContext context, ConversionMarker? markerClass) { - ConverterMarker? spec = specResult.Marker; - - if (spec is null) + if (markerClass is null) { return; } - var body = GenerateEfCoreTypes.GenerateOuter(spec.UnderlyingType, spec.VoSymbol.IsValueType, spec.VoSymbol); - var extensionMethod = GenerateEfCoreTypes.GenerateOuterExtensionMethod(spec); + var body = GenerateEfCoreTypes.GenerateBodyForAMarkerClass(markerClass); + var extensionMethod = GenerateEfCoreTypes.GenerateMarkerExtensionMethod(markerClass); - var fullNamespace = spec.SourceType.FullNamespace(); + var fullNamespace = markerClass.MarkerClassSymbol.FullNamespace(); - var isPublic = spec.SourceType.DeclaredAccessibility.HasFlag(Accessibility.Public); + var isPublic = markerClass.MarkerClassSymbol.DeclaredAccessibility.HasFlag(Accessibility.Public); var accessor = isPublic ? "public" : "internal"; var ns = string.IsNullOrEmpty(fullNamespace) ? string.Empty : $"namespace {fullNamespace};"; - string sb = $$""" #if NET8_0_OR_GREATER @@ -61,7 +56,7 @@ private static void WriteEachIfNeeded(SourceProductionContext context, Conversio {{ns}} -{{accessor}} partial class {{spec.SourceType.Name}} +{{accessor}} partial class {{markerClass.MarkerClassSymbol.Name}} { {{body}} } @@ -73,19 +68,16 @@ private static void WriteEachIfNeeded(SourceProductionContext context, Conversio SourceText sourceText = SourceText.From(sb, Encoding.UTF8); - var unsanitized = $"{spec.SourceType.ToDisplayString()}_{spec.VoSymbol.ToDisplayString()}.g.cs"; - string filename = Util.SanitizeToALegalFilename(unsanitized); + string filename = Util.GetLegalMarkerClassFilename(markerClass.MarkerClassSymbol, markerClass.VoSymbol, markerClass.Kind); Util.TryWriteUsingUniqueFilename(filename, context, sourceText); } - private static void WriteEncompassingExtensionMethod( - INamedTypeSymbol? classDefinitionMarkerClassSymbol, - IEnumerable conversionMarkerAttributeDefinitions, + private static void StoreExtensionMethodToRegisterAllInMarkerClass( + INamedTypeSymbol? markerSymbol, + IEnumerable markerAttributes, SourceProductionContext context) { - INamedTypeSymbol? markerSymbol = classDefinitionMarkerClassSymbol; - if (markerSymbol is null) { return; @@ -123,7 +115,9 @@ private static void WriteEncompassingExtensionMethod( SourceText sourceText = SourceText.From(source, Encoding.UTF8); - string filename = Util.SanitizeToALegalFilename($"{markerSymbol.ToDisplayString()}.g.cs"); + var filename = Util.GetLegalMarkerClassFilename(markerSymbol, ConversionMarkerKind.EFCore); + + //string filename = Util.SanitizeToALegalFilename($"{markerSymbol.ToDisplayString()}.g.cs"); Util.TryWriteUsingUniqueFilename(filename, context, sourceText); @@ -133,7 +127,7 @@ string GenerateBody() { StringBuilder sb = new StringBuilder(); - foreach (ConversionMarkerAttributeDefinition eachSpec in conversionMarkerAttributeDefinitions) + foreach (MarkerAttributeDefinition eachSpec in markerAttributes) { if (eachSpec.Marker is null) { diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs index dccee08d36..fa043bfbbe 100644 --- a/src/Vogen/GenerateCodeForMessagePack.cs +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -7,76 +7,122 @@ namespace Vogen; -public record MessagePackGeneratorParams( - string Namespace, - INamedTypeSymbol WrapperType, - INamedTypeSymbol UnderlyingType, - string WrapperAccessibility) + +internal class GenerateCodeForMessagePack { - public static MessagePackGeneratorParams FromWorkItem(VoWorkItem voWorkItem) + public static void GenerateForAMarkerClass(SourceProductionContext context, Compilation compilation, MarkerClassDefinition markerClass) { - var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); + var markerClassSymbol = markerClass.MarkerClassSymbol; + + string pns = markerClassSymbol.FullNamespace() ?? ""; + + string ns = pns.Length == 0 ? "" : $"namespace {pns};"; + + var isPublic = markerClassSymbol.DeclaredAccessibility.HasFlag(Accessibility.Public); var accessor = isPublic ? "public" : "internal"; - return new(voWorkItem.FullNamespace, voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); + + var s = $$""" + {{GeneratedCodeSegments.Preamble}} + + {{ns}} + + {{accessor}} partial class {{markerClassSymbol.Name}} + { + {{GenerateForEachAttribute()}} + } + + """; + + SourceText sourceText = Util.FormatSource(s); + + string filename = Util.GetLegalMarkerClassFilename(markerClass.MarkerClassSymbol, ConversionMarkerKind.MessagePack); + + Util.TryWriteUsingUniqueFilename(filename, context, sourceText); + + return; + + string GenerateForEachAttribute() + { + StringBuilder sb = new(); + + foreach (MarkerAttributeDefinition eachMarker in markerClass.AttributeDefinitions.Where(m => m.Marker?.Kind is ConversionMarkerKind.MessagePack)) + { + sb.AppendLine( + $$""" + {{GenerateSource("public", eachMarker.Marker!.VoSymbol, eachMarker.Marker.UnderlyingTypeSymbol)}} + """); + } + + return sb.ToString(); + } } -} -internal class GenerateCodeForMessagePack -{ - public static void Generate(SourceProductionContext context, Compilation compilation, List items) + public static void GenerateForApplicableValueObjects(SourceProductionContext context, Compilation compilation, List valueObjects) { if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) { return; } - List toWrite = items.Select(GenerateSourceAndFilename).ToList(); + var matchingVos = valueObjects.Where(i => i.Config.Conversions.HasFlag(Conversions.MessagePack)).ToList(); + + List items = matchingVos.Select(MessagePackStandalone.FromWorkItem).ToList(); + + List toWrite = items.Select( + p => GenerateSourceAndFilename(p.WrapperAccessibility, p.WrapperType, p.ContainerNamespace, p.UnderlyingType)).ToList(); foreach (var eachToWrite in toWrite) { - SourceText sourceText = SourceText.From(eachToWrite.SourceCode, Encoding.UTF8); + SourceText sourceText = Util.FormatSource(eachToWrite.SourceCode); Util.TryWriteUsingUniqueFilename(eachToWrite.Filename, context, sourceText); } } - public static void GenerateForApplicableWorkItems(SourceProductionContext context, Compilation compilation, List workItems) + public record FormatterSourceAndFilename(string FormatterFullyQualifiedName, string Filename, string SourceCode); + + private static FormatterSourceAndFilename GenerateSourceAndFilename( + string accessibility, + INamedTypeSymbol wrapperSymbol, + string theNamespace, + INamedTypeSymbol underlyingSymbol) { - if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) - { - return; - } + string wrapperName = Util.EscapeIfRequired(wrapperSymbol.Name); - var items = workItems.Where(i => i.Config.Conversions.HasFlag(Conversions.MessagePack)).ToList(); + var ns = string.IsNullOrEmpty(theNamespace) ? string.Empty : $"namespace {theNamespace};"; - var toWrite = items.Select(MessagePackGeneratorParams.FromWorkItem).ToList(); - - Generate(context, compilation, toWrite); - } + string sb = + $$""" + {{GeneratedCodeSegments.Preamble}} + + {{ns}} + + {{GenerateSource(accessibility, wrapperSymbol, underlyingSymbol)}} + """; - public record FormatterSourceAndFilename(string FormatterFullyQualifiedName, string Filename, string SourceCode); + var fn = string.IsNullOrEmpty(theNamespace) ? "" : theNamespace + "."; + string serializerFqn = $"{fn}{wrapperName}MessagePackFormatter"; - private static FormatterSourceAndFilename GenerateSourceAndFilename(MessagePackGeneratorParams p) - { - var fullNamespace = p.Namespace; + var unsanitized = $"{wrapperSymbol.ToDisplayString()}_messagepack.g.cs"; + string filename = Util.SanitizeToALegalFilename(unsanitized); + return new FormatterSourceAndFilename(serializerFqn, filename, sb); + } - var accessor = p.WrapperAccessibility; - var ns = string.IsNullOrEmpty(fullNamespace) ? string.Empty : $"namespace {fullNamespace};"; + private static string GenerateSource(string accessibility, INamedTypeSymbol wrapperSymbol, INamedTypeSymbol underlyingSymbol) + { + var accessor = accessibility; - string wrapperName = Util.EscapeIfRequired(p.WrapperType.Name); + string wrapperNameShort = Util.EscapeIfRequired(wrapperSymbol.Name); + string wrapperName = Util.EscapeIfRequired(wrapperSymbol.FullName() ?? wrapperSymbol.Name); - string underlyingTypeName = p.UnderlyingType.FullName() ?? p.WrapperType.Name; + string underlyingTypeName = underlyingSymbol.FullName() ?? wrapperSymbol.Name; string sb = $$""" - {{GeneratedCodeSegments.Preamble}} - - {{ns}} - - {{accessor}} partial class {{wrapperName}}MessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<{{wrapperName}}> + {{accessor}} partial class {{wrapperNameShort}}MessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<{{wrapperName}}> { public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrapperName}} value, global::MessagePack.MessagePackSerializerOptions options) => writer.Write(value.Value); @@ -90,13 +136,8 @@ public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrappe static extern {{wrapperName}} UnsafeDeserialize({{wrapperName}} @this, {{underlyingTypeName}} value); } """; - - var fn = string.IsNullOrEmpty(fullNamespace) ? "" : fullNamespace + "."; - string serializerFqn = $"{fn}{wrapperName}MessagePackFormatter"; - - var unsanitized = $"{p.WrapperType.ToDisplayString()}_messagepack.g.cs"; - string filename = Util.SanitizeToALegalFilename(unsanitized); - return new FormatterSourceAndFilename(serializerFqn, filename, sb); + + return sb; } private static string GenerateReadMethod() diff --git a/src/Vogen/GenerateCodeForMessagePackMarkers.cs b/src/Vogen/GenerateCodeForMessagePackMarkers.cs index 5e37b6a522..4495197f33 100644 --- a/src/Vogen/GenerateCodeForMessagePackMarkers.cs +++ b/src/Vogen/GenerateCodeForMessagePackMarkers.cs @@ -1,7 +1,5 @@ using System.Collections.Immutable; -using System.Linq; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; namespace Vogen; @@ -10,27 +8,11 @@ internal class GenerateCodeForMessagePackMarkers public static void GenerateForMarkerClasses( SourceProductionContext context, Compilation compilation, - ImmutableArray conversionMarkerClasses) + ImmutableArray conversionMarkerClasses) { - if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) + foreach (MarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) { - return; - } - - foreach (ConversionMarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) - { - var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConverterMarkerKind.MessagePack); - - var ps = matchingMarkers.Select(ConvertToParams).ToList(); - - GenerateCodeForMessagePack.Generate(context, compilation, ps); + GenerateCodeForMessagePack.GenerateForAMarkerClass(context, compilation, eachMarkerClass); } } - - private static MessagePackGeneratorParams ConvertToParams(ConversionMarkerAttributeDefinition spec) => - new( - spec.Marker!.SourceType.FullNamespace(), - spec.Marker!.VoSymbol, - spec.Marker!.UnderlyingType, - "public"); } \ No newline at end of file diff --git a/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs b/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs index bd37bb8375..a21ec9eee9 100644 --- a/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs +++ b/src/Vogen/Generators/Conversions/GenerateEfCoreTypes.cs @@ -4,17 +4,13 @@ namespace Vogen.Generators.Conversions; internal static class GenerateEfCoreTypes { - public static string GenerateInner( - INamedTypeSymbol primitiveType, - bool isWrapperAValueType, - INamedTypeSymbol voSymbol) => Generate(true, primitiveType, isWrapperAValueType, voSymbol); + public static string GenerateInner(INamedTypeSymbol primitiveType, bool isWrapperAValueType, INamedTypeSymbol voSymbol) => + Generate(isWritingAsInnerClass: true, primitiveType, isWrapperAValueType, voSymbol); - public static string GenerateOuter( - INamedTypeSymbol primitiveType, - bool isWrapperAValueType, - INamedTypeSymbol voSymbol) => Generate(false, primitiveType, isWrapperAValueType, voSymbol); + public static string GenerateBodyForAMarkerClass(ConversionMarker markerClass) => + Generate(isWritingAsInnerClass: false, markerClass.UnderlyingTypeSymbol, markerClass.VoSymbol.IsValueType, markerClass.VoSymbol); - public static string Generate(bool isWritingAsInnerClass, INamedTypeSymbol primitiveType, bool isWrapperAValueType, INamedTypeSymbol voSymbol) + private static string Generate(bool isWritingAsInnerClass, INamedTypeSymbol primitiveType, bool isWrapperAValueType, INamedTypeSymbol voSymbol) { string sectionToCut = isWritingAsInnerClass ? "__WHEN_OUTER__" : "__WHEN_INNER__"; string sectionToKeep = isWritingAsInnerClass ? "__WHEN_INNER__" : "__WHEN_OUTER__"; @@ -47,16 +43,19 @@ public static string Generate(bool isWritingAsInnerClass, INamedTypeSymbol primi return code; } - public static string GenerateOuterExtensionMethod(ConverterMarker spec) + public static string GenerateMarkerExtensionMethod(ConversionMarker marker) { - string voTypeName = spec.VoSymbol.FullName() ?? spec.VoSymbol.Name; + var voSymbol = marker.VoSymbol; + var markerClassSymbol = marker.MarkerClassSymbol; + + string voTypeName = voSymbol.FullName() ?? voSymbol.Name; string code = _extensionMethodForOuter; + + string generatedConverter = $"{markerClassSymbol.FullNamespace()}.{markerClassSymbol.Name}.{voSymbol.Name}EfCoreValueConverter"; + string generatedComparer = $"{markerClassSymbol.FullNamespace()}.{markerClassSymbol.Name}.{voSymbol.Name}EfCoreValueComparer"; - string generatedConverter = $"{spec.SourceType.FullNamespace()}.{spec.SourceType.Name}.{spec.VoSymbol.Name}EfCoreValueConverter"; - string generatedComparer = $"{spec.SourceType.FullNamespace()}.{spec.SourceType.Name}.{spec.VoSymbol.Name}EfCoreValueComparer"; - - code = code.Replace("__CLASS_PREFIX__", spec.VoSymbol.Name); + code = code.Replace("__CLASS_PREFIX__", voSymbol.Name); code = code.Replace("__GENERATED_CONVERTER_NAME__", generatedConverter); code = code.Replace("__GENERATED_COMPARER_NAME__", generatedComparer); code = code.Replace("VOTYPE", voTypeName); diff --git a/src/Vogen/MarkerAttribute2.cs b/src/Vogen/MarkerAttribute2.cs new file mode 100644 index 0000000000..50dfa9aec6 --- /dev/null +++ b/src/Vogen/MarkerAttribute2.cs @@ -0,0 +1,49 @@ +using Microsoft.CodeAnalysis; + +namespace Vogen; + +/// +/// Represents a marker for a MessagePack conversion +/// +/// The namespace of the containing marker class. +/// The type name of the containing marker class. +/// The symbol for the value object wrapper class. +/// The symbol for the underlying primitive type. +/// The accessibility (public, internal, etc.) of the generated type. +public record MarkerAttribute2( + string ContainerNamespace, + string ContainerTypeName, + INamedTypeSymbol WrapperType, + INamedTypeSymbol UnderlyingType, + string WrapperAccessibility) +{ + public static MarkerAttribute2 FromWorkItem(VoWorkItem voWorkItem) + { + var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); + var accessor = isPublic ? "public" : "internal"; + + return new(voWorkItem.FullNamespace, "", voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); + } +} + +/// +/// Represents a marker for a MessagePack conversion +/// +/// The namespace of the containing marker class. +/// The symbol for the value object wrapper class. +/// The symbol for the underlying primitive type. +/// The accessibility (public, internal, etc.) of the generated type. +public record MessagePackStandalone( + string ContainerNamespace, + INamedTypeSymbol WrapperType, + INamedTypeSymbol UnderlyingType, + string WrapperAccessibility) +{ + public static MessagePackStandalone FromWorkItem(VoWorkItem voWorkItem) + { + var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); + var accessor = isPublic ? "public" : "internal"; + + return new(voWorkItem.FullNamespace, voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); + } +} \ No newline at end of file diff --git a/src/Vogen/MarkerAttributeDefinition.cs b/src/Vogen/MarkerAttributeDefinition.cs new file mode 100644 index 0000000000..e5d8835c46 --- /dev/null +++ b/src/Vogen/MarkerAttributeDefinition.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Vogen; + +public enum ConversionMarkerKind +{ + Unrecognized, + EFCore, + MessagePack, +} + +/// +/// Represents the *definition* of a 'marker attribute, e.g. an 'EFCore marker' or 'message pack marker' - that is, a partial class decorated with an +/// attribute such as `EfCoreConverter`, or 'MemoryPackConverter'. This is the singular item; a particular attribute on the method, +/// and contains the symbol for the value object being referenced, a symbol for the underlying type of the value object, +/// and a symbol for the method containing the attribute. +/// +internal sealed class MarkerAttributeDefinition +{ + private MarkerAttributeDefinition(ConversionMarker? marker, IEnumerable diagnostics) + { + Marker = marker; + Diagnostics = diagnostics.ToList(); + } + + public ConversionMarker? Marker { get; } + + public List Diagnostics { get; } + + public static MarkerAttributeDefinition Error(ConversionMarkerKind kind, Diagnostic diag) => new(null, [diag]); + + public static MarkerAttributeDefinition Ok(ConversionMarkerKind kind, INamedTypeSymbol voSymbol, INamedTypeSymbol underlyingTypeSymbol, INamedTypeSymbol sourceSymbol) => + new(marker: new ConversionMarker(kind, voSymbol, underlyingTypeSymbol, sourceSymbol), diagnostics: []); +} \ No newline at end of file diff --git a/src/Vogen/MarkerClassDefinition.cs b/src/Vogen/MarkerClassDefinition.cs new file mode 100644 index 0000000000..90825012c4 --- /dev/null +++ b/src/Vogen/MarkerClassDefinition.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.CodeAnalysis; + +namespace Vogen; + +/// +/// Represents a 'marker class', which is a partial class with one or more 'marker attributes' e.g 'EfCoreConverter', or 'MessagePackFormatter', etc. +/// +internal sealed class MarkerClassDefinition +{ + public INamedTypeSymbol MarkerClassSymbol { get; } + + public MarkerClassDefinition(INamedTypeSymbol markerClassSymbol, IEnumerable markers) + { + MarkerClassSymbol = markerClassSymbol; + Results = markers.Where(r => r is not null)!; + } + + private IEnumerable Results { get; } + + public IEnumerable Diagnostics => Results.SelectMany(r => r.Diagnostics); + + public IEnumerable AttributeDefinitions => Results; +} \ No newline at end of file diff --git a/src/Vogen/Util.cs b/src/Vogen/Util.cs index 3a71665f0a..ee429eafac 100644 --- a/src/Vogen/Util.cs +++ b/src/Vogen/Util.cs @@ -436,6 +436,22 @@ static string GetMessageToReport(VoWorkItem item) => /// public static string GetModifiersForValueAndIsInitializedFields(VoWorkItem workItem) => workItem.Config.Conversions.HasFlag(Vogen.Conversions.XmlSerializable) ? "" : "readonly"; + + internal static string GetLegalMarkerClassFilename(INamedTypeSymbol markerClassSymbol, ConversionMarkerKind conversionKind) + { + var unsanitized = $"{markerClassSymbol.ToDisplayString()}.{conversionKind}.g.cs"; + string filename = Util.SanitizeToALegalFilename(unsanitized); + + return filename; + } + + internal static string GetLegalMarkerClassFilename(INamedTypeSymbol markerClassSymbol, INamedTypeSymbol voSymbol, ConversionMarkerKind conversionKind) + { + var unsanitized = $"{markerClassSymbol.ToDisplayString()}.{voSymbol.ToDisplayString()}.{conversionKind}.g.cs"; + string filename = Util.SanitizeToALegalFilename(unsanitized); + + return filename; + } } public static class DebugGeneration diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs index dfd37709de..79bee41315 100644 --- a/src/Vogen/ValueObjectGenerator.cs +++ b/src/Vogen/ValueObjectGenerator.cs @@ -69,7 +69,7 @@ private static Found GetTargets(SyntaxValueProvider syntaxProvider) transform: (ctx, _) => ManageAttributes.GetDefaultConfigFromGlobalAttribute(ctx)) .Where(static m => m is not null)!; - IncrementalValuesProvider converterMarkerClasses = syntaxProvider.CreateSyntaxProvider( + IncrementalValuesProvider converterMarkerClasses = syntaxProvider.CreateSyntaxProvider( predicate: (node, _) => ConversionMarkers.IsTarget(node), transform: (ctx, _) => ConversionMarkers.GetConversionMarkerClassDefinitionFromAttribute(ctx)) .Where(static m => m is not null)!; @@ -80,14 +80,14 @@ private static Found GetTargets(SyntaxValueProvider syntaxProvider) record struct Found( IncrementalValuesProvider Vos, IncrementalValuesProvider GlobalConfig, - IncrementalValuesProvider ConverterMarkerClasses); + IncrementalValuesProvider ConverterMarkerClasses); private static void Execute( Compilation compilation, VogenKnownSymbols vogenKnownSymbols, ImmutableArray targets, ImmutableArray globalConfigBuildResult, - ImmutableArray conversionMarkerClassDefinitions, + ImmutableArray markerClasses, SourceProductionContext spc) { var csharpCompilation = compilation as CSharpCompilation; @@ -98,9 +98,9 @@ private static void Execute( internalDiags.RecordTargets(targets); - var efSpecErrors = conversionMarkerClassDefinitions.SelectMany(x => x.Diagnostics); + var conversionMarkerErrors = markerClasses.SelectMany(x => x.Diagnostics); - foreach (var diagnostic in efSpecErrors) + foreach (var diagnostic in conversionMarkerErrors) { spc.ReportDiagnostic(diagnostic); } @@ -124,12 +124,12 @@ private static void Execute( GenerateCodeForOpenApiSchemaCustomization.WriteIfNeeded(globalConfig, spc, workItems, vogenKnownSymbols, compilation); - GenerateCodeForConversionMarkers.Generate(spc, compilation, conversionMarkerClassDefinitions); + GenerateCodeEfCoreMarkers.Generate(spc, compilation, markerClasses); // the user can specify to create the MessagePack generated code as an attribute // or as marker in another project. - GenerateCodeForMessagePack.GenerateForApplicableWorkItems(spc, compilation, workItems); - GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, conversionMarkerClassDefinitions); + GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems); + GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, markerClasses); GenerateCodeForBsonSerializers.WriteIfNeeded(spc, compilation, workItems); diff --git a/tests/AnalyzerTests/EfCoreTests.cs b/tests/AnalyzerTests/EfCoreTests.cs deleted file mode 100644 index 451ba787e7..0000000000 --- a/tests/AnalyzerTests/EfCoreTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Collections.Immutable; -using System.Linq; -using System.Threading.Tasks; -using FluentAssertions; -using Microsoft.CodeAnalysis; -using Shared; -using Vogen; - -namespace AnalyzerTests; - -public class EfCoreTests -{ - public class Marker_class_attributes_must_reference_value_objects - { - [Fact] - public async Task OK_when_they_all_reference_vos() - { - var source = """ - using System; - using Vogen; - - [ValueObject] - public partial struct Vo1; - - [EfCoreConverter] - public partial class EfCoreConverters; - """; - - await new TestRunner() - .WithSource(source) - .ValidateWith(diagnostics => diagnostics.Should().BeEmpty()) - .RunOn(TargetFramework.Net8_0); - } - - [Fact] - public async Task Errors_on_markers_that_are_not_vos() - { - var source = """ - using System; - using Vogen; - - public class NotAValueObject; - public class NotAValueObject2; - - [ValueObject] - public partial struct Vo1; - - [EfCoreConverter] - [EfCoreConverter] - [EfCoreConverter] - public partial class EfCoreConverters; - """; - - await new TestRunner() - .WithSource(source) - .ValidateWith(Validate) - .RunOn(TargetFramework.Net8_0); - return; - - static void Validate(ImmutableArray diagnostics) - { - diagnostics.Should().HaveCount(2); - diagnostics.Should().AllSatisfy(x => x.Id.Should().Be("VOG031")); - diagnostics.Where( - d => d.GetMessage() == - "Type 'EfCoreConverters' specifies a target value object of NotAValueObject but it is not a value object") - .Should() - .HaveCount(1); - - diagnostics.Where( - d => d.GetMessage() == - "Type 'EfCoreConverters' specifies a target value object of NotAValueObject2 but it is not a value object") - .Should() - .HaveCount(1); - } - } - } -} \ No newline at end of file diff --git a/tests/AnalyzerTests/MarkerClassTests.cs b/tests/AnalyzerTests/MarkerClassTests.cs new file mode 100644 index 0000000000..da543ee79b --- /dev/null +++ b/tests/AnalyzerTests/MarkerClassTests.cs @@ -0,0 +1,164 @@ +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.CodeAnalysis; +using Shared; +using Vogen; + +namespace AnalyzerTests; + +public class MarkerClassTests +{ + public class Attributes_must_reference_value_objects + { + [Fact] + public async Task OK_when_they_all_reference_vos() + { + var source = """ + using System; + using Vogen; + + [ValueObject] + public partial struct Vo1; + + [EfCoreConverter] + public partial class EfCoreConverters; + """; + + await new TestRunner() + .WithSource(source) + .ValidateWith(diagnostics => diagnostics.Should().BeEmpty()) + .RunOn(TargetFramework.Net8_0); + } + + [Fact] + public async Task Errors_when_attributes_reference_non_vos() + { + var source = """ + using System; + using Vogen; + + public class NotAValueObject; + public class NotAValueObject2; + + [ValueObject] + public partial struct Vo1; + + [EfCoreConverter] + [EfCoreConverter] + [EfCoreConverter] + public partial class EfCoreConverters; + """; + + await new TestRunner() + .WithSource(source) + .ValidateWith(Validate) + .RunOn(TargetFramework.Net8_0); + return; + + static void Validate(ImmutableArray diagnostics) + { + diagnostics.Should().HaveCount(2); + diagnostics.Should().AllSatisfy(x => x.Id.Should().Be("VOG031")); + + diagnostics.Where( + d => d.GetMessage() == + "Marker class 'EfCoreConverters' specifies a target value object 'NotAValueObject', but that is not a value object") + .Should() + .HaveCount(1); + + diagnostics.Where( + d => d.GetMessage() == + "Marker class 'EfCoreConverters' specifies a target value object 'NotAValueObject2', but that is not a value object") + .Should() + .HaveCount(1); + } + } + } + + public class Attributes_must_reference_value_objects_that_have_explicitly_specified_underlying_primitive + { + [Fact] + public async Task OK_when_they_all_reference_vos() + { + var source = """ + using System; + using Vogen; + + [ValueObject] + public partial struct GoodVo; + + [ValueObject] + public partial struct BadVo; + + [EfCoreConverter] + [EfCoreConverter] + public partial class EfCoreConverters; + """; + + await new TestRunner() + .WithSource(source) + .ValidateWith(Validate) + .RunOn(TargetFramework.Net8_0); + return; + + static void Validate(ImmutableArray diagnostics) + { + diagnostics.Should().HaveCount(1); + diagnostics.Should().AllSatisfy(x => x.Id.Should().Be("VOG035")); + + diagnostics.Where( + d => d.GetMessage() == + "Marker class 'EfCoreConverters' specifies a target value object 'BadVo', but that type does not explicitly specify the primitive type that it wraps") + .Should() + .HaveCount(1); + } + + } + + [Fact] + public async Task Errors_when_attributes_reference_non_vos() + { + var source = """ + using System; + using Vogen; + + public class NotAValueObject; + public class NotAValueObject2; + + [ValueObject] + public partial struct Vo1; + + [EfCoreConverter] + [EfCoreConverter] + [EfCoreConverter] + public partial class EfCoreConverters; + """; + + await new TestRunner() + .WithSource(source) + .ValidateWith(Validate) + .RunOn(TargetFramework.Net8_0); + return; + + static void Validate(ImmutableArray diagnostics) + { + diagnostics.Should().HaveCount(2); + diagnostics.Should().AllSatisfy(x => x.Id.Should().Be("VOG031")); + + diagnostics.Where( + d => d.GetMessage() == + "Marker class 'EfCoreConverters' specifies a target value object 'NotAValueObject', but that is not a value object") + .Should() + .HaveCount(1); + + diagnostics.Where( + d => d.GetMessage() == + "Marker class 'EfCoreConverters' specifies a target value object 'NotAValueObject2', but that is not a value object") + .Should() + .HaveCount(1); + } + } + } +} \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs index 385402b7ba..090a7b8a82 100644 --- a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs +++ b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs @@ -39,12 +39,13 @@ public async Task Generates_messagepack_markers() using System; using Vogen; - namespace Whatever; + namespace @double; - [ValueObject(conversions: Conversions.None)] + [ValueObject(conversions: Conversions.None)] public partial struct MyId; [MessagePack] + [EfCoreConverter] public partial class MyMarkers; """; diff --git a/tests/Testbench/MyInt.cs b/tests/Testbench/MyInt.cs new file mode 100644 index 0000000000..ba1bf803b1 --- /dev/null +++ b/tests/Testbench/MyInt.cs @@ -0,0 +1,6 @@ +using Vogen; + +namespace N1; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MyInt; \ No newline at end of file diff --git a/tests/Testbench/MyString.cs b/tests/Testbench/MyString.cs new file mode 100644 index 0000000000..728318eb72 --- /dev/null +++ b/tests/Testbench/MyString.cs @@ -0,0 +1,6 @@ +using Vogen; + +namespace N2; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MyString; \ No newline at end of file diff --git a/tests/Testbench/Program.cs b/tests/Testbench/Program.cs index ce801ee440..cb6942e50a 100644 --- a/tests/Testbench/Program.cs +++ b/tests/Testbench/Program.cs @@ -5,16 +5,16 @@ using System.Linq; using System.Xml.Serialization; using MessagePack; +using N1; +using N2; using Vogen; // ReSharper disable UnusedVariable namespace Testbench; - -[ValueObject(conversions: Conversions.MessagePack)] -public partial class MyInt; - [MessagePack()] +[MessagePack()] +[EfCoreConverter] public partial class MyMarkers; public static class Program From 918e020029cf4426cc15d2cf38376f2d2026ca14 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Tue, 12 Nov 2024 07:08:37 +0000 Subject: [PATCH 03/10] Fix warnings --- ...ildConverterMarkerDefinitionsFromAttributes.cs | 15 --------------- src/Vogen/Diagnostics/DiagnosticsCatalogue.cs | 11 +---------- 2 files changed, 1 insertion(+), 25 deletions(-) delete mode 100644 src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs diff --git a/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs b/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs deleted file mode 100644 index b3efe1767e..0000000000 --- a/src/Vogen/BuildConverterMarkerDefinitionsFromAttributes.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; -using Vogen.Diagnostics; - -// ReSharper disable NullableWarningSuppressionIsUsed - -namespace Vogen; - -internal static class BuildConverterMarkerDefinitionsFromAttributes -{ - - -} \ No newline at end of file diff --git a/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs b/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs index b8fc063252..d6b09a0096 100644 --- a/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs +++ b/src/Vogen/Diagnostics/DiagnosticsCatalogue.cs @@ -3,6 +3,7 @@ using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +// ReSharper disable UseCollectionExpression namespace Vogen.Diagnostics; @@ -58,11 +59,6 @@ internal static class DiagnosticsCatalogue "Invalid Deserialization Strictness", $"The Deserialization Strictness specified does not match any known customizations - see the {nameof(DeserializationStrictness)} type for valid values"); - private static readonly DiagnosticDescriptor _mismatchedParsableGeneration = CreateDescriptor( - RuleIdentifiers.InvalidDeserializationStrictness, - "Invalid Parsable Generation", - $"The Parsable Generation specified does not match the underlying primitive"); - private static readonly DiagnosticDescriptor _underlyingTypeMustNotBeSameAsValueObject = CreateDescriptor( RuleIdentifiers.UnderlyingTypeMustNotBeSameAsValueObject, "Invalid underlying type", @@ -173,8 +169,6 @@ public static Diagnostic UnderlyingTypeCannotBeCollection(INamedTypeSymbol voCla public static Diagnostic InvalidCustomizations(Location location) => Create(_invalidCustomizations, location); public static Diagnostic InvalidDeserializationStrictness(Location location) => Create(_invalidDeserializationStrictness, location); - - public static Diagnostic InvalidParsableGeneration(Location location) => Create(_mismatchedParsableGeneration, location); public static Diagnostic InstanceMethodCannotHaveNullArgumentName(INamedTypeSymbol voClass) => Create(_instanceMethodCannotHaveNullArgumentName, voClass.Locations, voClass.Name); @@ -213,9 +207,6 @@ private static DiagnosticDescriptor CreateDescriptor(string code, string title, public static Diagnostic BuildDiagnostic(DiagnosticDescriptor descriptor, string name, Location location) => Diagnostic.Create(descriptor, location, name); - public static Diagnostic BuildDiagnostic(DiagnosticDescriptor descriptor, string name) => - Diagnostic.Create(descriptor, null, name); - private static Diagnostic Create(DiagnosticDescriptor descriptor, IEnumerable locations, params object?[] args) { var locationsList = (locations as IReadOnlyList) ?? locations.ToList(); From 95db4bfbd36e3990c5249f9a6454e9bcde03a8e9 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Tue, 12 Nov 2024 07:32:42 +0000 Subject: [PATCH 04/10] Don't emit markers if nothing applicable found --- ...ers.cs => GenerateCodeForEfCoreMarkers.cs} | 9 +- src/Vogen/GenerateCodeForMessagePack.cs | 5 + src/Vogen/ValueObjectGenerator.cs | 2 +- .../GeneralStuff/GeneralTests.cs | 25 + ...essagepack_and_efcore_markers.verified.txt | 773 ++++++++++++++++++ ...Generates_messagepack_markers.verified.txt | 655 ++++++++++++++- 6 files changed, 1465 insertions(+), 4 deletions(-) rename src/Vogen/{GenerateCodeEfCoreMarkers.cs => GenerateCodeForEfCoreMarkers.cs} (96%) create mode 100644 tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt diff --git a/src/Vogen/GenerateCodeEfCoreMarkers.cs b/src/Vogen/GenerateCodeForEfCoreMarkers.cs similarity index 96% rename from src/Vogen/GenerateCodeEfCoreMarkers.cs rename to src/Vogen/GenerateCodeForEfCoreMarkers.cs index 12ff999ef7..3103e7164a 100644 --- a/src/Vogen/GenerateCodeEfCoreMarkers.cs +++ b/src/Vogen/GenerateCodeForEfCoreMarkers.cs @@ -9,7 +9,7 @@ namespace Vogen; -internal class GenerateCodeEfCoreMarkers +internal class GenerateCodeForEfCoreMarkers { public static void Generate(SourceProductionContext context, Compilation compilation, ImmutableArray markerClasses) { @@ -20,7 +20,12 @@ public static void Generate(SourceProductionContext context, Compilation compila foreach (MarkerClassDefinition? eachMarkerClass in markerClasses) { - var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConversionMarkerKind.EFCore); + var matchingMarkers = eachMarkerClass.AttributeDefinitions.Where(a => a.Marker?.Kind == ConversionMarkerKind.EFCore).ToList(); + + if (matchingMarkers.Count == 0) + { + return; + } StoreExtensionMethodToRegisterAllInMarkerClass(eachMarkerClass.MarkerClassSymbol, matchingMarkers, context); diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs index fa043bfbbe..d1f7619835 100644 --- a/src/Vogen/GenerateCodeForMessagePack.cs +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -13,6 +13,11 @@ internal class GenerateCodeForMessagePack public static void GenerateForAMarkerClass(SourceProductionContext context, Compilation compilation, MarkerClassDefinition markerClass) { var markerClassSymbol = markerClass.MarkerClassSymbol; + + if (!markerClass.AttributeDefinitions.Any(m => m.Marker?.Kind is ConversionMarkerKind.MessagePack)) + { + return; + } string pns = markerClassSymbol.FullNamespace() ?? ""; diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs index 79bee41315..fdbbfa50ee 100644 --- a/src/Vogen/ValueObjectGenerator.cs +++ b/src/Vogen/ValueObjectGenerator.cs @@ -124,7 +124,7 @@ private static void Execute( GenerateCodeForOpenApiSchemaCustomization.WriteIfNeeded(globalConfig, spc, workItems, vogenKnownSymbols, compilation); - GenerateCodeEfCoreMarkers.Generate(spc, compilation, markerClasses); + GenerateCodeForEfCoreMarkers.Generate(spc, compilation, markerClasses); // the user can specify to create the MessagePack generated code as an attribute // or as marker in another project. diff --git a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs index 090a7b8a82..b9b253c3b0 100644 --- a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs +++ b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs @@ -44,6 +44,31 @@ namespace @double; [ValueObject(conversions: Conversions.None)] public partial struct MyId; + [MessagePack] + public partial class MyMarkers; + + """; + + await new SnapshotRunner() + .WithSource(source) + .WithPackage(new NuGetPackage("MessagePack", "2.5.187", "lib/netstandard2.0" )) + .RunOn(TargetFramework.Net8_0); + } + + [Fact] + public async Task Generates_messagepack_and_efcore_markers() + { + var source = + $$""" + + using System; + using Vogen; + + namespace @double; + + [ValueObject(conversions: Conversions.None)] + public partial struct MyId; + [MessagePack] [EfCoreConverter] public partial class MyMarkers; diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt new file mode 100644 index 0000000000..55831887d8 --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt @@ -0,0 +1,773 @@ +[ +#if NET8_0_OR_GREATER + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 + +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 + +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 + +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 + +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 + +namespace @double; + + public static class MyMarkers__Ext + { + public static global::Microsoft.EntityFrameworkCore.ModelConfigurationBuilder RegisterAllInMyMarkers(this global::Microsoft.EntityFrameworkCore.ModelConfigurationBuilder configurationBuilder) + { + configurationBuilder.Properties<@double.MyId>().HaveConversion<@double.MyMarkers.MyIdEfCoreValueConverter, @double.MyMarkers.MyIdEfCoreValueComparer>(); + + + return configurationBuilder; + } + } + +#endif + +#if NET8_0_OR_GREATER + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ + +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 + +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 + +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 + +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 + +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 + +namespace @double; + +public partial class MyMarkers +{ + public class MyIdEfCoreValueConverter : global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter<@double.MyId, System.Int32> + { + public MyIdEfCoreValueConverter() : this(null) { } + public MyIdEfCoreValueConverter(global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ConverterMappingHints mappingHints = null) + : base( + vo => vo.Value, + value => Deserialize(value), + mappingHints + ) { } + + static @double.MyId Deserialize(System.Int32 value) => UnsafeDeserialize(default, value); + + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern @double.MyId UnsafeDeserialize(@double.MyId @this, System.Int32 value); + } + public class MyIdEfCoreValueComparer : global::Microsoft.EntityFrameworkCore.ChangeTracking.ValueComparer<@double.MyId> + { + public MyIdEfCoreValueComparer() : base( + (left, right) => DoCompare(left, right), + instance => instance.IsInitialized() ? instance.GetHashCode() : 0) + { + } + + static bool DoCompare(@double.MyId left, @double.MyId right) + { + // if neither are initialized, then they're equal + if(!left.IsInitialized() && !right.IsInitialized()) return true; + + return left.IsInitialized() && right.IsInitialized() && UnderlyingValue(left).Equals(UnderlyingValue(right)); + } + private static System.Int32 UnderlyingValue(@double.MyId i) => UnsafeValueField(ref i); + + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field, Name = "_value")] + static extern ref System.Int32 UnsafeValueField(ref @double.MyId @this); + } +} + +public static class MyId__Ext +{ + public static global::Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<@double.MyId> HasVogenConversion(this global::Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder<@double.MyId> propertyBuilder) => + propertyBuilder.HasConversion<@double.MyMarkers.MyIdEfCoreValueConverter, @double.MyMarkers.MyIdEfCoreValueComparer>(); +} + + +#endif + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace @double; +public partial class MyMarkers +{ + public partial class MyIdMessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<@double.MyId> + { + public void Serialize(ref global::MessagePack.MessagePackWriter writer, @double.MyId value, global::MessagePack.MessagePackSerializerOptions options) => writer.Write(value.Value); + public @double.MyId Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => Deserialize(reader.ReadInt32()); + static @double.MyId Deserialize(System.Int32 value) => UnsafeDeserialize(default, value); + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern @double.MyId UnsafeDeserialize(@double.MyId @this, System.Int32 value); + } +} + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace generator; +public class VogenTypesFactory : global::System.Text.Json.Serialization.JsonConverterFactory +{ + public VogenTypesFactory() + { + } + + private static readonly global::System.Collections.Generic.Dictionary> _lookup = new global::System.Collections.Generic.Dictionary> + { + }; + public override bool CanConvert(global::System.Type typeToConvert) => _lookup.ContainsKey(typeToConvert); + public override global::System.Text.Json.Serialization.JsonConverter CreateConverter(global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) => _lookup[typeToConvert].Value; +} + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace @double +{ + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] + [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyIdDebugView))] + [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] + // ReSharper disable once UnusedType.Global + public partial struct MyId : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable, global::System.IFormattable, global::System.ISpanFormattable, global::System.IUtf8SpanFormattable + { +#if DEBUG +private readonly global::System.Diagnostics.StackTrace _stackTrace = null!; +#endif +#if !VOGEN_NO_VALIDATION + private readonly global::System.Boolean _isInitialized; +#endif + private readonly System.Int32 _value; + /// + /// Gets the underlying value if set, otherwise a is thrown. + /// + public readonly System.Int32 Value + { + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + EnsureInitialized(); + return _value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyId() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyId(System.Int32 value) + { + _value = value; +#if !VOGEN_NO_VALIDATION + _isInitialized = true; +#endif + } + + /// + /// Builds an instance from the provided underlying type. + /// + /// The underlying type. + /// An instance of this type. + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static MyId From(System.Int32 value) + { + return new MyId(value); + } + + /// + /// Tries to build an instance from the provided underlying type. + /// If a normalization method is provided, it will be called. + /// If validation is provided, and it fails, false will be returned. + /// + /// The underlying type. + /// An instance of the value object. + /// True if the value object can be built, otherwise false. + +#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + public static bool TryFrom( +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + System.Int32 value, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] +#endif + out MyId vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + vo = new MyId(value); + return true; + } + + /// + /// Tries to build an instance from the provided underlying value. + /// If a normalization method is provided, it will be called. + /// If validation is provided, and it fails, an error will be returned. + /// + /// The primitive value. + /// A containing either the value object, or an error. + public static Vogen.ValueObjectOrError TryFrom(System.Int32 value) + { + return new Vogen.ValueObjectOrError(new MyId(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if VOGEN_NO_VALIDATION +#pragma warning disable CS8775 + public readonly bool IsInitialized() => true; +#pragma warning restore CS8775 +#else + public readonly bool IsInitialized() => _isInitialized; +#endif + public static explicit operator MyId(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyId value) => value.Value; + // only called internally when something has been deserialized into + // its primitive type. + private static MyId __Deserialize(System.Int32 value) + { + return new MyId(value); + } + + public readonly global::System.Boolean Equals(MyId other) + { + // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals. + // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type. + if (!IsInitialized() || !other.IsInitialized()) + return false; + return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); + } + + public global::System.Boolean Equals(MyId other, global::System.Collections.Generic.IEqualityComparer comparer) + { + return comparer.Equals(this, other); + } + + public readonly global::System.Boolean Equals(System.Int32 primitive) + { + return Value.Equals(primitive); + } + + public readonly override global::System.Boolean Equals(global::System.Object obj) + { + return obj is MyId && Equals((MyId)obj); + } + + public static global::System.Boolean operator ==(MyId left, MyId right) => left.Equals(right); + public static global::System.Boolean operator !=(MyId left, MyId right) => !(left == right); + public static global::System.Boolean operator ==(MyId left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyId right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyId right) => !(left == right); + public static global::System.Boolean operator !=(MyId left, System.Int32 right) => !(left == right); + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + public int CompareTo(object other) + { + if (other is null) + return 1; + if (other is MyId x) + return CompareTo(x); + ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type MyId", nameof(other)); + return 0; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(utf8Text, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(utf8Text, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s) + { + var r = System.Int32.Parse(s); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.Globalization.NumberStyles style) + { + var r = System.Int32.Parse(s, style); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + +#nullable disable + /// + public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format, global::System.IFormatProvider provider) + { + return IsInitialized() ? Value.ToString(format, provider) : "[UNINITIALIZED]"; + } + + /// + public bool TryFormat(global::System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider) + { + charsWritten = default; + return IsInitialized() ? Value.TryFormat(destination, out charsWritten, format, provider) : false; + } + + /// + public bool TryFormat(global::System.Span utf8Destination, out int bytesWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider) + { + bytesWritten = default; + return IsInitialized() ? Value.TryFormat(utf8Destination, out bytesWritten, format, provider) : false; + } + +#nullable restore + public readonly override global::System.Int32 GetHashCode() + { + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + } + + /// + public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]"; + /// + public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]"; + /// + public global::System.String ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format) => IsInitialized() ? Value.ToString(format) ?? "" : "[UNINITIALIZED]"; + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private readonly void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + ThrowHelper.ThrowWhenNotInitialized(_stackTrace); +#else + ThrowHelper.ThrowWhenNotInitialized(); +#endif + } + } + +#nullable disable + internal sealed class MyIdDebugView + { + private readonly MyId _t; + MyIdDebugView(MyId t) + { + _t = t; + } + + public global::System.Boolean IsInitialized => _t.IsInitialized(); + public global::System.String UnderlyingType => "System.Int32"; + public global::System.String Value => _t.IsInitialized() ? _t._value.ToString() : "[not initialized]"; +#if DEBUG + public global::System.String CreatedWith => _t._stackTrace.ToString() ?? "the From method"; +#endif + public global::System.String Conversions => @"None"; + } + +#nullable restore + static class ThrowHelper + { +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenCreatedWithNull() => throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenNotInitialized() => throw new global::Vogen.ValueObjectValidationException("Use of uninitialized Value Object."); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw new global::Vogen.ValueObjectValidationException("Use of uninitialized Value Object at: " + stackTrace ?? ""); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenValidationFails(Vogen.Validation validation) + { + var ex = new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + if (validation.Data is not null) + { + foreach (var kvp in validation.Data) + { + ex.Data[kvp.Key] = kvp.Value; + } + } + + throw ex; + } + } + } +} +] \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt index 5f282702bb..7a22ec065f 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt @@ -1 +1,654 @@ - \ No newline at end of file +[ +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace @double; +public partial class MyMarkers +{ + public partial class MyIdMessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<@double.MyId> + { + public void Serialize(ref global::MessagePack.MessagePackWriter writer, @double.MyId value, global::MessagePack.MessagePackSerializerOptions options) => writer.Write(value.Value); + public @double.MyId Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => Deserialize(reader.ReadInt32()); + static @double.MyId Deserialize(System.Int32 value) => UnsafeDeserialize(default, value); + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern @double.MyId UnsafeDeserialize(@double.MyId @this, System.Int32 value); + } +} + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace generator; +public class VogenTypesFactory : global::System.Text.Json.Serialization.JsonConverterFactory +{ + public VogenTypesFactory() + { + } + + private static readonly global::System.Collections.Generic.Dictionary> _lookup = new global::System.Collections.Generic.Dictionary> + { + }; + public override bool CanConvert(global::System.Type typeToConvert) => _lookup.ContainsKey(typeToConvert); + public override global::System.Text.Json.Serialization.JsonConverter CreateConverter(global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) => _lookup[typeToConvert].Value; +} + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace @double +{ + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] + [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyIdDebugView))] + [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] + // ReSharper disable once UnusedType.Global + public partial struct MyId : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable, global::System.IFormattable, global::System.ISpanFormattable, global::System.IUtf8SpanFormattable + { +#if DEBUG +private readonly global::System.Diagnostics.StackTrace _stackTrace = null!; +#endif +#if !VOGEN_NO_VALIDATION + private readonly global::System.Boolean _isInitialized; +#endif + private readonly System.Int32 _value; + /// + /// Gets the underlying value if set, otherwise a is thrown. + /// + public readonly System.Int32 Value + { + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + EnsureInitialized(); + return _value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyId() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyId(System.Int32 value) + { + _value = value; +#if !VOGEN_NO_VALIDATION + _isInitialized = true; +#endif + } + + /// + /// Builds an instance from the provided underlying type. + /// + /// The underlying type. + /// An instance of this type. + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static MyId From(System.Int32 value) + { + return new MyId(value); + } + + /// + /// Tries to build an instance from the provided underlying type. + /// If a normalization method is provided, it will be called. + /// If validation is provided, and it fails, false will be returned. + /// + /// The underlying type. + /// An instance of the value object. + /// True if the value object can be built, otherwise false. + +#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + public static bool TryFrom( +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + System.Int32 value, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] +#endif + out MyId vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + vo = new MyId(value); + return true; + } + + /// + /// Tries to build an instance from the provided underlying value. + /// If a normalization method is provided, it will be called. + /// If validation is provided, and it fails, an error will be returned. + /// + /// The primitive value. + /// A containing either the value object, or an error. + public static Vogen.ValueObjectOrError TryFrom(System.Int32 value) + { + return new Vogen.ValueObjectOrError(new MyId(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if VOGEN_NO_VALIDATION +#pragma warning disable CS8775 + public readonly bool IsInitialized() => true; +#pragma warning restore CS8775 +#else + public readonly bool IsInitialized() => _isInitialized; +#endif + public static explicit operator MyId(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyId value) => value.Value; + // only called internally when something has been deserialized into + // its primitive type. + private static MyId __Deserialize(System.Int32 value) + { + return new MyId(value); + } + + public readonly global::System.Boolean Equals(MyId other) + { + // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals. + // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type. + if (!IsInitialized() || !other.IsInitialized()) + return false; + return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); + } + + public global::System.Boolean Equals(MyId other, global::System.Collections.Generic.IEqualityComparer comparer) + { + return comparer.Equals(this, other); + } + + public readonly global::System.Boolean Equals(System.Int32 primitive) + { + return Value.Equals(primitive); + } + + public readonly override global::System.Boolean Equals(global::System.Object obj) + { + return obj is MyId && Equals((MyId)obj); + } + + public static global::System.Boolean operator ==(MyId left, MyId right) => left.Equals(right); + public static global::System.Boolean operator !=(MyId left, MyId right) => !(left == right); + public static global::System.Boolean operator ==(MyId left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyId right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyId right) => !(left == right); + public static global::System.Boolean operator !=(MyId left, System.Int32 right) => !(left == right); + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + public int CompareTo(object other) + { + if (other is null) + return 1; + if (other is MyId x) + return CompareTo(x); + ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type MyId", nameof(other)); + return 0; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(utf8Text, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(utf8Text, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s) + { + var r = System.Int32.Parse(s); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.Globalization.NumberStyles style) + { + var r = System.Int32.Parse(s, style); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + +#nullable disable + /// + public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format, global::System.IFormatProvider provider) + { + return IsInitialized() ? Value.ToString(format, provider) : "[UNINITIALIZED]"; + } + + /// + public bool TryFormat(global::System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider) + { + charsWritten = default; + return IsInitialized() ? Value.TryFormat(destination, out charsWritten, format, provider) : false; + } + + /// + public bool TryFormat(global::System.Span utf8Destination, out int bytesWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider) + { + bytesWritten = default; + return IsInitialized() ? Value.TryFormat(utf8Destination, out bytesWritten, format, provider) : false; + } + +#nullable restore + public readonly override global::System.Int32 GetHashCode() + { + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + } + + /// + public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]"; + /// + public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]"; + /// + public global::System.String ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format) => IsInitialized() ? Value.ToString(format) ?? "" : "[UNINITIALIZED]"; + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private readonly void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + ThrowHelper.ThrowWhenNotInitialized(_stackTrace); +#else + ThrowHelper.ThrowWhenNotInitialized(); +#endif + } + } + +#nullable disable + internal sealed class MyIdDebugView + { + private readonly MyId _t; + MyIdDebugView(MyId t) + { + _t = t; + } + + public global::System.Boolean IsInitialized => _t.IsInitialized(); + public global::System.String UnderlyingType => "System.Int32"; + public global::System.String Value => _t.IsInitialized() ? _t._value.ToString() : "[not initialized]"; +#if DEBUG + public global::System.String CreatedWith => _t._stackTrace.ToString() ?? "the From method"; +#endif + public global::System.String Conversions => @"None"; + } + +#nullable restore + static class ThrowHelper + { +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenCreatedWithNull() => throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenNotInitialized() => throw new global::Vogen.ValueObjectValidationException("Use of uninitialized Value Object."); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw new global::Vogen.ValueObjectValidationException("Use of uninitialized Value Object at: " + stackTrace ?? ""); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenValidationFails(Vogen.Validation validation) + { + var ex = new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + if (validation.Data is not null) + { + foreach (var kvp in validation.Data) + { + ex.Data[kvp.Key] = kvp.Value; + } + } + + throw ex; + } + } + } +} +] \ No newline at end of file From e29a05cfebfde9d77670a6900182d5c5b2c15793 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Tue, 12 Nov 2024 08:36:02 +0000 Subject: [PATCH 05/10] Updated snapshot tests --- ...alTests.Generates_messagepack.verified.txt | 652 +++++++++++++++++- 1 file changed, 651 insertions(+), 1 deletion(-) diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt index 5f282702bb..8490c458b7 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack.verified.txt @@ -1 +1,651 @@ - \ No newline at end of file +[ +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace Whatever; +public partial class MyIdMessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter +{ + public void Serialize(ref global::MessagePack.MessagePackWriter writer, Whatever.MyId value, global::MessagePack.MessagePackSerializerOptions options) => writer.Write(value.Value); + public Whatever.MyId Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => Deserialize(reader.ReadInt32()); + static Whatever.MyId Deserialize(System.Int32 value) => UnsafeDeserialize(default, value); + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern Whatever.MyId UnsafeDeserialize(Whatever.MyId @this, System.Int32 value); +} + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace generator; +public class VogenTypesFactory : global::System.Text.Json.Serialization.JsonConverterFactory +{ + public VogenTypesFactory() + { + } + + private static readonly global::System.Collections.Generic.Dictionary> _lookup = new global::System.Collections.Generic.Dictionary> + { + }; + public override bool CanConvert(global::System.Type typeToConvert) => _lookup.ContainsKey(typeToConvert); + public override global::System.Text.Json.Serialization.JsonConverter CreateConverter(global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) => _lookup[typeToConvert].Value; +} + +// ------------------------------------------------------------------------------ +// +// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen) +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ +// Suppress warnings about [Obsolete] member usage in generated code. +#pragma warning disable CS0618 +// Suppress warnings for 'Override methods on comparable types'. +#pragma warning disable CA1036 +// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators +#pragma warning disable MA0097 +// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.' +// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations. +#pragma warning disable CS8669, CS8632 +// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' +#pragma warning disable CS1591 +namespace Whatever +{ + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] + [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyIdDebugView))] + [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] + // ReSharper disable once UnusedType.Global + public partial struct MyId : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable, global::System.IFormattable, global::System.ISpanFormattable, global::System.IUtf8SpanFormattable + { +#if DEBUG +private readonly global::System.Diagnostics.StackTrace _stackTrace = null!; +#endif +#if !VOGEN_NO_VALIDATION + private readonly global::System.Boolean _isInitialized; +#endif + private readonly System.Int32 _value; + /// + /// Gets the underlying value if set, otherwise a is thrown. + /// + public readonly System.Int32 Value + { + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + get + { + EnsureInitialized(); + return _value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyId() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyId(System.Int32 value) + { + _value = value; +#if !VOGEN_NO_VALIDATION + _isInitialized = true; +#endif + } + + /// + /// Builds an instance from the provided underlying type. + /// + /// The underlying type. + /// An instance of this type. + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static MyId From(System.Int32 value) + { + return new MyId(value); + } + + /// + /// Tries to build an instance from the provided underlying type. + /// If a normalization method is provided, it will be called. + /// If validation is provided, and it fails, false will be returned. + /// + /// The underlying type. + /// An instance of the value object. + /// True if the value object can be built, otherwise false. + +#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + public static bool TryFrom( +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + System.Int32 value, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] +#endif + out MyId vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + vo = new MyId(value); + return true; + } + + /// + /// Tries to build an instance from the provided underlying value. + /// If a normalization method is provided, it will be called. + /// If validation is provided, and it fails, an error will be returned. + /// + /// The primitive value. + /// A containing either the value object, or an error. + public static Vogen.ValueObjectOrError TryFrom(System.Int32 value) + { + return new Vogen.ValueObjectOrError(new MyId(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if VOGEN_NO_VALIDATION +#pragma warning disable CS8775 + public readonly bool IsInitialized() => true; +#pragma warning restore CS8775 +#else + public readonly bool IsInitialized() => _isInitialized; +#endif + public static explicit operator MyId(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyId value) => value.Value; + // only called internally when something has been deserialized into + // its primitive type. + private static MyId __Deserialize(System.Int32 value) + { + return new MyId(value); + } + + public readonly global::System.Boolean Equals(MyId other) + { + // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals. + // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type. + if (!IsInitialized() || !other.IsInitialized()) + return false; + return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); + } + + public global::System.Boolean Equals(MyId other, global::System.Collections.Generic.IEqualityComparer comparer) + { + return comparer.Equals(this, other); + } + + public readonly global::System.Boolean Equals(System.Int32 primitive) + { + return Value.Equals(primitive); + } + + public readonly override global::System.Boolean Equals(global::System.Object obj) + { + return obj is MyId && Equals((MyId)obj); + } + + public static global::System.Boolean operator ==(MyId left, MyId right) => left.Equals(right); + public static global::System.Boolean operator !=(MyId left, MyId right) => !(left == right); + public static global::System.Boolean operator ==(MyId left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyId right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyId right) => !(left == right); + public static global::System.Boolean operator !=(MyId left, System.Int32 right) => !(left == right); + public int CompareTo(MyId other) => Value.CompareTo(other.Value); + public int CompareTo(object other) + { + if (other is null) + return 1; + if (other is MyId x) + return CompareTo(x); + ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type MyId", nameof(other)); + return 0; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, global::System.IFormatProvider provider, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization). + /// + public static global::System.Boolean TryParse(string s, +#if NETCOREAPP3_0_OR_GREATER +[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] +#endif + out MyId result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyId(__v); + return true; + } + + result = default; + return false; + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(utf8Text, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(utf8Text, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s) + { + var r = System.Int32.Parse(s); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.Globalization.NumberStyles style) + { + var r = System.Int32.Parse(s, style); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, style, provider); + return From(r); + } + + /// + /// + /// + /// + /// The value created by calling the Parse method on the primitive. + /// + /// Thrown when the value can be parsed, but is not valid. + public static MyId Parse(string s, global::System.IFormatProvider provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + +#nullable disable + /// + public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format, global::System.IFormatProvider provider) + { + return IsInitialized() ? Value.ToString(format, provider) : "[UNINITIALIZED]"; + } + + /// + public bool TryFormat(global::System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider) + { + charsWritten = default; + return IsInitialized() ? Value.TryFormat(destination, out charsWritten, format, provider) : false; + } + + /// + public bool TryFormat(global::System.Span utf8Destination, out int bytesWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider) + { + bytesWritten = default; + return IsInitialized() ? Value.TryFormat(utf8Destination, out bytesWritten, format, provider) : false; + } + +#nullable restore + public readonly override global::System.Int32 GetHashCode() + { + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + } + + /// + public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]"; + /// + public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]"; + /// + public global::System.String ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format) => IsInitialized() ? Value.ToString(format) ?? "" : "[UNINITIALIZED]"; + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private readonly void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + ThrowHelper.ThrowWhenNotInitialized(_stackTrace); +#else + ThrowHelper.ThrowWhenNotInitialized(); +#endif + } + } + +#nullable disable + internal sealed class MyIdDebugView + { + private readonly MyId _t; + MyIdDebugView(MyId t) + { + _t = t; + } + + public global::System.Boolean IsInitialized => _t.IsInitialized(); + public global::System.String UnderlyingType => "System.Int32"; + public global::System.String Value => _t.IsInitialized() ? _t._value.ToString() : "[not initialized]"; +#if DEBUG + public global::System.String CreatedWith => _t._stackTrace.ToString() ?? "the From method"; +#endif + public global::System.String Conversions => @"MessagePack"; + } + +#nullable restore + static class ThrowHelper + { +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenCreatedWithNull() => throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenNotInitialized() => throw new global::Vogen.ValueObjectValidationException("Use of uninitialized Value Object."); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw new global::Vogen.ValueObjectValidationException("Use of uninitialized Value Object at: " + stackTrace ?? ""); +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute] +#endif + internal static void ThrowWhenValidationFails(Vogen.Validation validation) + { + var ex = new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + if (validation.Data is not null) + { + foreach (var kvp in validation.Data) + { + ex.Data[kvp.Key] = kvp.Value; + } + } + + throw ex; + } + } + } +} +] \ No newline at end of file From 7884c8a8ccafd9324f4604be93e1974b71956480 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Tue, 12 Nov 2024 17:50:13 +0000 Subject: [PATCH 06/10] Filled out reader to accomodate more types. Added manifest --- src/Vogen/GenerateCodeForMessagePack.cs | 105 +++++++++++++++++++----- tests/Testbench/Program.cs | 66 +++++++++++++-- 2 files changed, 144 insertions(+), 27 deletions(-) diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs index d1f7619835..9c30e0a256 100644 --- a/src/Vogen/GenerateCodeForMessagePack.cs +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -7,7 +7,6 @@ namespace Vogen; - internal class GenerateCodeForMessagePack { public static void GenerateForAMarkerClass(SourceProductionContext context, Compilation compilation, MarkerClassDefinition markerClass) @@ -18,11 +17,11 @@ public static void GenerateForAMarkerClass(SourceProductionContext context, Comp { return; } - + string pns = markerClassSymbol.FullNamespace() ?? ""; - + string ns = pns.Length == 0 ? "" : $"namespace {pns};"; - + var isPublic = markerClassSymbol.DeclaredAccessibility.HasFlag(Accessibility.Public); var accessor = isPublic ? "public" : "internal"; @@ -34,7 +33,8 @@ public static void GenerateForAMarkerClass(SourceProductionContext context, Comp {{accessor}} partial class {{markerClassSymbol.Name}} { - {{GenerateForEachAttribute()}} + {{GenerateManifest()}} + {{GenerateFormatters()}} } """; @@ -47,11 +47,40 @@ public static void GenerateForAMarkerClass(SourceProductionContext context, Comp return; - string GenerateForEachAttribute() + string GenerateManifest() + { + return + $$""" + {{accessor}} static global::MessagePack.Formatters.IMessagePackFormatter[] MessagePackFormatters => new global::MessagePack.Formatters.IMessagePackFormatter[] + { + {{GenerateEach()}} + }; + """; + + string GenerateEach() + { + string?[] names = markerClass.AttributeDefinitions.Where( + m => m.Marker?.Kind is ConversionMarkerKind.MessagePack).Select( + x => + { + if (x is null) return null; + if (x.Marker is null) return null; + + string? wrapperNameShort = x.Marker.VoSymbol.Name; + + return $"new {wrapperNameShort}MessagePackFormatter()"; + }).ToArray(); + + return string.Join(", ", names); + } + } + + string GenerateFormatters() { StringBuilder sb = new(); - foreach (MarkerAttributeDefinition eachMarker in markerClass.AttributeDefinitions.Where(m => m.Marker?.Kind is ConversionMarkerKind.MessagePack)) + foreach (MarkerAttributeDefinition eachMarker in markerClass.AttributeDefinitions.Where( + m => m.Marker?.Kind is ConversionMarkerKind.MessagePack)) { sb.AppendLine( $$""" @@ -63,8 +92,9 @@ string GenerateForEachAttribute() } } - - public static void GenerateForApplicableValueObjects(SourceProductionContext context, Compilation compilation, List valueObjects) + public static void GenerateForApplicableValueObjects(SourceProductionContext context, + Compilation compilation, + List valueObjects) { if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) { @@ -77,7 +107,7 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con List toWrite = items.Select( p => GenerateSourceAndFilename(p.WrapperAccessibility, p.WrapperType, p.ContainerNamespace, p.UnderlyingType)).ToList(); - + foreach (var eachToWrite in toWrite) { SourceText sourceText = Util.FormatSource(eachToWrite.SourceCode); @@ -89,9 +119,9 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con public record FormatterSourceAndFilename(string FormatterFullyQualifiedName, string Filename, string SourceCode); private static FormatterSourceAndFilename GenerateSourceAndFilename( - string accessibility, - INamedTypeSymbol wrapperSymbol, - string theNamespace, + string accessibility, + INamedTypeSymbol wrapperSymbol, + string theNamespace, INamedTypeSymbol underlyingSymbol) { string wrapperName = Util.EscapeIfRequired(wrapperSymbol.Name); @@ -101,9 +131,9 @@ private static FormatterSourceAndFilename GenerateSourceAndFilename( string sb = $$""" {{GeneratedCodeSegments.Preamble}} - + {{ns}} - + {{GenerateSource(accessibility, wrapperSymbol, underlyingSymbol)}} """; @@ -124,6 +154,13 @@ private static string GenerateSource(string accessibility, INamedTypeSymbol wrap string wrapperName = Util.EscapeIfRequired(wrapperSymbol.FullName() ?? wrapperSymbol.Name); string underlyingTypeName = underlyingSymbol.FullName() ?? wrapperSymbol.Name; + + string readMethod = GenerateReadMethod(); + + if (readMethod.Length == 0) + { + return "#error unsupported underlying type " + underlyingSymbol.SpecialType; + } string sb = $$""" @@ -133,7 +170,7 @@ public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrappe writer.Write(value.Value); public {{wrapperName}} Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => - Deserialize(reader.{{GenerateReadMethod()}}); + Deserialize(reader.{{readMethod}}); static {{wrapperName}} Deserialize({{underlyingTypeName}} value) => UnsafeDeserialize(default, value); @@ -143,10 +180,38 @@ public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrappe """; return sb; - } - private static string GenerateReadMethod() - { - return "ReadInt32()"; + string GenerateReadMethod() + { + if(underlyingSymbol.SpecialType == SpecialType.System_Boolean) + return "ReadBoolean()"; + if(underlyingSymbol.SpecialType == SpecialType.System_SByte) + return "ReadSByte()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Byte) + return "ReadByte()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Char) + return "ReadChar()"; + if(underlyingSymbol.SpecialType == SpecialType.System_DateTime) + return "ReadDateTime()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Double) + return "ReadDouble()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Single) + return "ReadSingle()"; + if(underlyingSymbol.SpecialType == SpecialType.System_String) + return "ReadString()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Int16) + return "ReadInt16()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Int32) + return "ReadInt32()"; + if(underlyingSymbol.SpecialType == SpecialType.System_Int64) + return "ReadInt64()"; + if(underlyingSymbol.SpecialType == SpecialType.System_UInt16) + return "ReadUInt16()"; + if(underlyingSymbol.SpecialType == SpecialType.System_UInt32) + return "ReadUInt32()"; + if(underlyingSymbol.SpecialType == SpecialType.System_UInt64) + return "ReadUInt64()"; + return ""; + } } } \ No newline at end of file diff --git a/tests/Testbench/Program.cs b/tests/Testbench/Program.cs index cb6942e50a..606582a606 100644 --- a/tests/Testbench/Program.cs +++ b/tests/Testbench/Program.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.IO; -using System.Linq; -using System.Xml.Serialization; using MessagePack; +using MessagePack.Formatters; using N1; using N2; using Vogen; @@ -13,13 +9,69 @@ namespace Testbench; [MessagePack()] +[MessagePack()] +[MessagePack()] +[MessagePack()] [MessagePack()] [EfCoreConverter] -public partial class MyMarkers; +internal partial class MyMarkers; + +[ValueObject] +public partial struct MyBool +{ +} public static class Program { public static void Main() { + // Create an instance of the sample class + var originalObject = new Sample + { + Id = MyId.From(123), + Name = Name.From("Test"), + Active = MyBool.From(true) + }; + + +// Caret is currently at line 47 + +// Create custom resolver with the MyIdFormatter + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + MyMarkers.MessagePackFormatters, +// new IMessagePackFormatter[] { new MyMarkers.MyIdMessagePackFormatter(), new MyMarkers.NameMessagePackFormatter(), new MyMarkers.MyBoolMessagePackFormatter() }, + new IFormatterResolver[] { MessagePack.Resolvers.StandardResolver.Instance } + ); + + var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + + byte[] serializedObject = MessagePackSerializer.Serialize(originalObject, options); + + +// Deserialize the byte array back to the Sample object using the custom options + var deserializedObject = MessagePackSerializer.Deserialize(serializedObject, options); + +// Display the deserialized object + Console.WriteLine($"Id: {deserializedObject.Id}, Name: {deserializedObject.Name}, Active: {deserializedObject.Active}"); + } -} \ No newline at end of file +} + + +[MessagePackObject] +public class Sample +{ + [MessagePack.Key(0)] + public MyId Id { get; set; } + + [MessagePack.Key(1)] public Name Name { get; set; } = Name.From(""); + [MessagePack.Key(2)] public MyBool Active { get; set; } = MyBool.From(false); +} + +[ValueObject] +public partial struct MyId; + +[ValueObject] +public partial struct Name; + + From 03c96a58777e79f232178ac65fc69302e183db41 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Wed, 13 Nov 2024 09:18:04 +0000 Subject: [PATCH 07/10] Added integration tests for MessagePack --- .../topics/reference/Integration.md | 16 + ...ackScenario_using_conversion_attributes.cs | 63 ++ .../MessagePackScenario_using_markers.cs | 68 ++ samples/Vogen.Examples/Vogen.Examples.csproj | 1 + src/Vogen/GenerateCodeForMessagePack.cs | 147 ++-- .../GenerateCodeForMessagePackMarkers.cs | 10 +- src/Vogen/KnownSymbols.cs | 3 + src/Vogen/ValueObjectGenerator.cs | 4 +- tests/ConsumerTests/ConsumerTests.csproj | 1 + .../SerializationAndConversionTests/Bar.cs | 3 + .../ClassVos/AnyOtherTypeVoTests.cs | 1 + .../ClassVos/MessagePackSerializationTests.cs | 237 ++++++ .../ClassVos/Types/FooVo.cs | 2 - .../ClassVos/Types/MessagePackTypes.cs | 49 ++ .../ComplexSerializationTests.cs | 725 ++++++++++++++++-- .../ComplexSerializationTests_Bson.cs | 9 +- ...ComplexSerializationTests_SytemTextJson.cs | 10 +- .../FooFormatter.cs | 26 + .../RecordClassVos/AnyOtherTypeVoTests.cs | 1 + .../MessagePackSerializationTests.cs | 256 +++++++ .../RecordClassVos/Types/FooVo.cs | 2 - .../RecordClassVos/Types/MessagePackTypes.cs | 49 ++ .../RecordStructVos/AnyOtherTypeVoTests.cs | 1 + .../MessagePackSerializationTests.cs | 256 +++++++ .../RecordStructVos/Types/FooVo.cs | 2 - .../RecordStructVos/Types/MessagePackTypes.cs | 49 ++ .../StructVos/AnyOtherTypeVoTests.cs | 1 + .../MessagePackSerializationTests.cs | 256 +++++++ .../StructVos/StringVoTests.cs | 12 +- .../StructVos/Types/FooVo.cs | 2 - .../StructVos/Types/MessagePackTypes.cs | 49 ++ tests/Testbench/Program.cs | 43 +- 32 files changed, 2189 insertions(+), 165 deletions(-) create mode 100644 samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_conversion_attributes.cs create mode 100644 samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_markers.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/Bar.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/ClassVos/MessagePackSerializationTests.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/MessagePackTypes.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/FooFormatter.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/MessagePackTypes.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/MessagePackTypes.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/MessagePackTypes.cs diff --git a/docs/site/Writerside/topics/reference/Integration.md b/docs/site/Writerside/topics/reference/Integration.md index 84a3c10c87..9fe0e6e1f6 100644 --- a/docs/site/Writerside/topics/reference/Integration.md +++ b/docs/site/Writerside/topics/reference/Integration.md @@ -79,6 +79,22 @@ public enum Conversions /// Creates a BSON serializer for each value object. /// Bson = 1 << 8, + + /// + /// Creates and registers a codec and copier for Microsoft Orleans. + /// This feature requires .NET 8 and C#12 and cannot be polly-filled. + /// + Orleans = 1 << 9, + + /// + /// Generates implementation of IXmlSerializable. + /// + XmlSerializable = 1 << 10, + + /// + /// Generates implementation of IMessagePackFormatter. + /// + MessagePack = 1 << 11 } ``` diff --git a/samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_conversion_attributes.cs b/samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_conversion_attributes.cs new file mode 100644 index 0000000000..57159a4245 --- /dev/null +++ b/samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_conversion_attributes.cs @@ -0,0 +1,63 @@ +#if NULLABLE_DISABLED_BUILD +#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. +#endif + +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using MessagePack; +using MessagePack.Formatters; + +namespace Vogen.Examples.SerializationAndConversion.MessagePackScenario.UsingConversionAttributes; + +[ValueObject(conversions: Conversions.MessagePack)] +public readonly partial struct Age; + +[ValueObject(conversions: Conversions.MessagePack)] +public readonly partial struct PersonId; + +[ValueObject(conversions: Conversions.MessagePack)] +public readonly partial struct Name; + +[UsedImplicitly] +[MessagePackObject] +public class Person +{ + [Key(0)] + public PersonId Id { get; set; } + + [Key(1)] + public Name Name { get; set; } + + [Key(2)] + public Age Age { get; set; } +} + +[UsedImplicitly] +public class MessagePackScenario_using_conversion_attributes : IScenario +{ + public Task Run() + { + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [new PersonIdMessagePackFormatter(), new NameMessagePackFormatter(), new AgeMessagePackFormatter()], + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + + var originalObject = new Person + { + Id = PersonId.From(123), + Name = Name.From("Test"), + Age = Age.From(42) + }; + + byte[] serializedObject = MessagePackSerializer.Serialize(originalObject, options); + + var deserializedObject = MessagePackSerializer.Deserialize(serializedObject, options); + + Console.WriteLine($"Id: {deserializedObject.Id}, Name: {deserializedObject.Name}, Active: {deserializedObject.Age}"); + + return Task.CompletedTask; + } +} diff --git a/samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_markers.cs b/samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_markers.cs new file mode 100644 index 0000000000..8eff8c4ac6 --- /dev/null +++ b/samples/Vogen.Examples/SerializationAndConversion/MessagePack/MessagePackScenario_using_markers.cs @@ -0,0 +1,68 @@ +#if NULLABLE_DISABLED_BUILD +#pragma warning disable CS8632 // The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. +#endif + +using System; +using System.Threading.Tasks; +using JetBrains.Annotations; +using MessagePack; +using MessagePack.Formatters; + +namespace Vogen.Examples.SerializationAndConversion.MessagePackScenario.UsingMarkers; + +[ValueObject] +public readonly partial struct Age; + +[ValueObject] +public readonly partial struct PersonId; + +[ValueObject] +public readonly partial struct Name; + +[UsedImplicitly] +[MessagePackObject] +public class Person +{ + [Key(0)] + public PersonId Id { get; set; } + + [Key(1)] + public Name Name { get; set; } + + [Key(2)] + public Age Age { get; set; } +} + +[MessagePack] +[MessagePack] +[MessagePack] +public partial class Markers; + +[UsedImplicitly] +public class MessagePackScenario_using_markers : IScenario +{ + public Task Run() + { + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + Markers.MessagePackFormatters, + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + + var originalObject = new Person + { + Id = PersonId.From(123), + Name = Name.From("Test"), + Age = Age.From(42) + }; + + byte[] serializedObject = MessagePackSerializer.Serialize(originalObject, options); + + var deserializedObject = MessagePackSerializer.Deserialize(serializedObject, options); + + Console.WriteLine($"Id: {deserializedObject.Id}, Name: {deserializedObject.Name}, Active: {deserializedObject.Age}"); + + return Task.CompletedTask; + } +} diff --git a/samples/Vogen.Examples/Vogen.Examples.csproj b/samples/Vogen.Examples/Vogen.Examples.csproj index 9116cfb4b7..b3f79b8137 100644 --- a/samples/Vogen.Examples/Vogen.Examples.csproj +++ b/samples/Vogen.Examples/Vogen.Examples.csproj @@ -16,6 +16,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs index 9c30e0a256..10f96fc95e 100644 --- a/src/Vogen/GenerateCodeForMessagePack.cs +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -9,7 +9,10 @@ namespace Vogen; internal class GenerateCodeForMessagePack { - public static void GenerateForAMarkerClass(SourceProductionContext context, Compilation compilation, MarkerClassDefinition markerClass) + public static void GenerateForAMarkerClass(SourceProductionContext context, + Compilation compilation, + MarkerClassDefinition markerClass, + VogenKnownSymbols vogenKnownSymbols) { var markerClassSymbol = markerClass.MarkerClassSymbol; @@ -84,7 +87,7 @@ string GenerateFormatters() { sb.AppendLine( $$""" - {{GenerateSource("public", eachMarker.Marker!.VoSymbol, eachMarker.Marker.UnderlyingTypeSymbol)}} + {{GenerateSource("public", eachMarker.Marker!.VoSymbol, eachMarker.Marker.UnderlyingTypeSymbol, vogenKnownSymbols)}} """); } @@ -94,7 +97,8 @@ string GenerateFormatters() public static void GenerateForApplicableValueObjects(SourceProductionContext context, Compilation compilation, - List valueObjects) + List valueObjects, + VogenKnownSymbols knownSymbols) { if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) { @@ -106,7 +110,7 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con List items = matchingVos.Select(MessagePackStandalone.FromWorkItem).ToList(); List toWrite = items.Select( - p => GenerateSourceAndFilename(p.WrapperAccessibility, p.WrapperType, p.ContainerNamespace, p.UnderlyingType)).ToList(); + p => GenerateSourceAndFilename(p.WrapperAccessibility, p.WrapperType, p.ContainerNamespace, p.UnderlyingType, knownSymbols)).ToList(); foreach (var eachToWrite in toWrite) { @@ -118,11 +122,11 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con public record FormatterSourceAndFilename(string FormatterFullyQualifiedName, string Filename, string SourceCode); - private static FormatterSourceAndFilename GenerateSourceAndFilename( - string accessibility, + private static FormatterSourceAndFilename GenerateSourceAndFilename(string accessibility, INamedTypeSymbol wrapperSymbol, string theNamespace, - INamedTypeSymbol underlyingSymbol) + INamedTypeSymbol underlyingSymbol, + VogenKnownSymbols knownSymbols) { string wrapperName = Util.EscapeIfRequired(wrapperSymbol.Name); @@ -134,7 +138,7 @@ private static FormatterSourceAndFilename GenerateSourceAndFilename( {{ns}} - {{GenerateSource(accessibility, wrapperSymbol, underlyingSymbol)}} + {{GenerateSource(accessibility, wrapperSymbol, underlyingSymbol, knownSymbols)}} """; var fn = string.IsNullOrEmpty(theNamespace) ? "" : theNamespace + "."; @@ -146,72 +150,89 @@ private static FormatterSourceAndFilename GenerateSourceAndFilename( } - private static string GenerateSource(string accessibility, INamedTypeSymbol wrapperSymbol, INamedTypeSymbol underlyingSymbol) + private static string GenerateSource(string accessibility, + INamedTypeSymbol wrapperSymbol, + INamedTypeSymbol underlyingSymbol, + VogenKnownSymbols vogenKnownSymbols) { var accessor = accessibility; string wrapperNameShort = Util.EscapeIfRequired(wrapperSymbol.Name); string wrapperName = Util.EscapeIfRequired(wrapperSymbol.FullName() ?? wrapperSymbol.Name); - string underlyingTypeName = underlyingSymbol.FullName() ?? wrapperSymbol.Name; + string underlyingTypeName = underlyingSymbol.FullName() ?? underlyingSymbol.Name; - string readMethod = GenerateReadMethod(); + // if (readAndWriteMethods.Item1.Length == 0) + // { + // return $"#error unsupported underlying type '{underlyingSymbol.FullName()}' for value object '{wrapperSymbol.Name}' - you need to turn off MessagePack support for this value object and provide your own resolver"; + // } + + string nativeReadMethod = TryGetNativeReadMethod(underlyingSymbol); - if (readMethod.Length == 0) + if (!string.IsNullOrEmpty(nativeReadMethod)) { - return "#error unsupported underlying type " + underlyingSymbol.SpecialType; + return $$""" + {{accessor}} partial class {{wrapperNameShort}}MessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<{{wrapperName}}> + { + public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrapperName}} value, global::MessagePack.MessagePackSerializerOptions options) => + writer.Write(value.Value); + + public {{wrapperName}} Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => + Deserialize(reader.{{nativeReadMethod}}); + + static {{wrapperName}} Deserialize({{underlyingTypeName}} value) => UnsafeDeserialize(default, value); + + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern {{wrapperName}} UnsafeDeserialize({{wrapperName}} @this, {{underlyingTypeName}} value); + } + """; } - string sb = - $$""" - {{accessor}} partial class {{wrapperNameShort}}MessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<{{wrapperName}}> - { - public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrapperName}} value, global::MessagePack.MessagePackSerializerOptions options) => - writer.Write(value.Value); - - public {{wrapperName}} Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) => - Deserialize(reader.{{readMethod}}); - - static {{wrapperName}} Deserialize({{underlyingTypeName}} value) => UnsafeDeserialize(default, value); - - [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] - static extern {{wrapperName}} UnsafeDeserialize({{wrapperName}} @this, {{underlyingTypeName}} value); - } - """; - - return sb; + return $$""" + {{accessor}} partial class {{wrapperNameShort}}MessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<{{wrapperName}}> + { + public void Serialize(ref global::MessagePack.MessagePackWriter writer, {{wrapperName}} value, global::MessagePack.MessagePackSerializerOptions options) + { + global::MessagePack.Formatters.IMessagePackFormatter<{{underlyingTypeName}}>? r = options.Resolver.GetFormatter<{{underlyingTypeName}}>(); + if (r is null) Throw("No formatter for underlying type of '{{underlyingTypeName}}' registered for value object '{{wrapperName}}'."); + r.Serialize(ref writer, value.Value, options); + } + + public {{wrapperName}} Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) + { + global::MessagePack.Formatters.IMessagePackFormatter<{{underlyingTypeName}}>? r = options.Resolver.GetFormatter<{{underlyingTypeName}}>(); + if (r is null) Throw("No formatter for underlying type of '{{underlyingTypeName}}' registered for value object '{{wrapperName}}'."); + {{underlyingTypeName}} g = r.Deserialize(ref reader, options); + return Deserialize(g); + } + + private static void Throw(string message) => throw new global::MessagePack.MessagePackSerializationException(message); + + static {{wrapperName}} Deserialize({{underlyingTypeName}} value) => UnsafeDeserialize(default, value); + + [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")] + static extern {{wrapperName}} UnsafeDeserialize({{wrapperName}} @this, {{underlyingTypeName}} value); + } + """; + } - string GenerateReadMethod() + private static string TryGetNativeReadMethod(INamedTypeSymbol primitive) => + primitive.SpecialType switch { - if(underlyingSymbol.SpecialType == SpecialType.System_Boolean) - return "ReadBoolean()"; - if(underlyingSymbol.SpecialType == SpecialType.System_SByte) - return "ReadSByte()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Byte) - return "ReadByte()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Char) - return "ReadChar()"; - if(underlyingSymbol.SpecialType == SpecialType.System_DateTime) - return "ReadDateTime()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Double) - return "ReadDouble()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Single) - return "ReadSingle()"; - if(underlyingSymbol.SpecialType == SpecialType.System_String) - return "ReadString()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Int16) - return "ReadInt16()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Int32) - return "ReadInt32()"; - if(underlyingSymbol.SpecialType == SpecialType.System_Int64) - return "ReadInt64()"; - if(underlyingSymbol.SpecialType == SpecialType.System_UInt16) - return "ReadUInt16()"; - if(underlyingSymbol.SpecialType == SpecialType.System_UInt32) - return "ReadUInt32()"; - if(underlyingSymbol.SpecialType == SpecialType.System_UInt64) - return "ReadUInt64()"; - return ""; - } - } + SpecialType.System_Boolean => "ReadBoolean()", + SpecialType.System_SByte => "ReadSByte()", + SpecialType.System_Byte => "ReadByte()", + SpecialType.System_Char => "ReadChar()", + SpecialType.System_DateTime => "ReadDateTime()", + SpecialType.System_Double => "ReadDouble()", + SpecialType.System_Single => "ReadSingle()", + SpecialType.System_String => "ReadString()", + SpecialType.System_Int16 => "ReadInt16()", + SpecialType.System_Int32 => "ReadInt32()", + SpecialType.System_Int64 => "ReadInt64()", + SpecialType.System_UInt16 => "ReadUInt16()", + SpecialType.System_UInt32 => "ReadUInt32()", + SpecialType.System_UInt64 => "ReadUInt64()", + _ => "" + }; } \ No newline at end of file diff --git a/src/Vogen/GenerateCodeForMessagePackMarkers.cs b/src/Vogen/GenerateCodeForMessagePackMarkers.cs index 4495197f33..b9116908f3 100644 --- a/src/Vogen/GenerateCodeForMessagePackMarkers.cs +++ b/src/Vogen/GenerateCodeForMessagePackMarkers.cs @@ -5,14 +5,14 @@ namespace Vogen; internal class GenerateCodeForMessagePackMarkers { - public static void GenerateForMarkerClasses( - SourceProductionContext context, - Compilation compilation, - ImmutableArray conversionMarkerClasses) + public static void GenerateForMarkerClasses(SourceProductionContext context, + Compilation compilation, + ImmutableArray conversionMarkerClasses, + VogenKnownSymbols vogenKnownSymbols) { foreach (MarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) { - GenerateCodeForMessagePack.GenerateForAMarkerClass(context, compilation, eachMarkerClass); + GenerateCodeForMessagePack.GenerateForAMarkerClass(context, compilation, eachMarkerClass, vogenKnownSymbols); } } } \ No newline at end of file diff --git a/src/Vogen/KnownSymbols.cs b/src/Vogen/KnownSymbols.cs index 7d752040ac..dad795c37a 100644 --- a/src/Vogen/KnownSymbols.cs +++ b/src/Vogen/KnownSymbols.cs @@ -117,6 +117,9 @@ public class KnownSymbols(Compilation compilation) public INamedTypeSymbol? FSharpMap => GetOrResolveType("Microsoft.FSharp.Collections.FSharpMap`2", ref _FSharpMap); private Option _FSharpMap; + public INamedTypeSymbol? Guid => GetOrResolveType("System.Guid", ref _Guid); + private Option _Guid; + /// /// A "simple type" in this context defines a type that is either diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs index fdbbfa50ee..faef6b8523 100644 --- a/src/Vogen/ValueObjectGenerator.cs +++ b/src/Vogen/ValueObjectGenerator.cs @@ -128,8 +128,8 @@ private static void Execute( // the user can specify to create the MessagePack generated code as an attribute // or as marker in another project. - GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems); - GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, markerClasses); + GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems, vogenKnownSymbols); + GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, markerClasses, vogenKnownSymbols); GenerateCodeForBsonSerializers.WriteIfNeeded(spc, compilation, workItems); diff --git a/tests/ConsumerTests/ConsumerTests.csproj b/tests/ConsumerTests/ConsumerTests.csproj index fd527b3be7..8b0f164f89 100644 --- a/tests/ConsumerTests/ConsumerTests.csproj +++ b/tests/ConsumerTests/ConsumerTests.csproj @@ -34,6 +34,7 @@ + diff --git a/tests/ConsumerTests/SerializationAndConversionTests/Bar.cs b/tests/ConsumerTests/SerializationAndConversionTests/Bar.cs new file mode 100644 index 0000000000..3d93b0a4ca --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/Bar.cs @@ -0,0 +1,3 @@ +namespace Vogen.IntegrationTests.TestTypes; + +public record struct Bar(int Age, string Name); \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/AnyOtherTypeVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/AnyOtherTypeVoTests.cs index 0b5b7829e4..6b2e1e6ecc 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/AnyOtherTypeVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/AnyOtherTypeVoTests.cs @@ -9,6 +9,7 @@ using LinqToDB.Mapping; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Vogen.IntegrationTests.TestTypes; using Vogen.IntegrationTests.TestTypes.ClassVos; using NewtonsoftJsonSerializer = Newtonsoft.Json.JsonConvert; using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/MessagePackSerializationTests.cs new file mode 100644 index 0000000000..0282212355 --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/MessagePackSerializationTests.cs @@ -0,0 +1,237 @@ +using MessagePack; +using Vogen.IntegrationTests.TestTypes; +using Vogen.IntegrationTests.TestTypes.ClassVos; + +// ReSharper disable NullableWarningSuppressionIsUsed + +namespace ConsumerTests.SerializationAndConversionTests.ClassVos; + +public class MessagePackSetup +{ + +} + +public class MessagePackSerializationTests +{ + private readonly MessagePackBoolVoMessagePackFormatter _boolVo = new MessagePackBoolVoMessagePackFormatter(); + private readonly MessagePackFloatVoMessagePackFormatter _floatVo = new MessagePackFloatVoMessagePackFormatter(); + private readonly MessagePackByteVoMessagePackFormatter _byteVo = new MessagePackByteVoMessagePackFormatter(); + private readonly MessagePackCharVoMessagePackFormatter _charVo = new MessagePackCharVoMessagePackFormatter(); + private readonly MessagePackDateOnlyVoMessagePackFormatter _dateOnlyVo = new MessagePackDateOnlyVoMessagePackFormatter(); + + private readonly MessagePackDateTimeOffsetVoMessagePackFormatter _dateTimeOffsetVo = + new MessagePackDateTimeOffsetVoMessagePackFormatter(); + + private readonly MessagePackDateTimeVoMessagePackFormatter _dateTimeVo = new MessagePackDateTimeVoMessagePackFormatter(); + private readonly MessagePackDecimalVoMessagePackFormatter _decimalVo = new MessagePackDecimalVoMessagePackFormatter(); + private readonly MessagePackDoubleVoMessagePackFormatter _doubleVo = new MessagePackDoubleVoMessagePackFormatter(); + private readonly MessagePackFooVoMessagePackFormatter _fooVo = new MessagePackFooVoMessagePackFormatter(); + private readonly MessagePackGuidVoMessagePackFormatter _guidVo = new MessagePackGuidVoMessagePackFormatter(); + private readonly MessagePackIntVoMessagePackFormatter _intVo = new MessagePackIntVoMessagePackFormatter(); + private readonly MessagePackLongVoMessagePackFormatter _longVo = new MessagePackLongVoMessagePackFormatter(); + private readonly MessagePackShortVoMessagePackFormatter _shortVo = new MessagePackShortVoMessagePackFormatter(); + private readonly MessagePackStringVoMessagePackFormatter _stringVo = new MessagePackStringVoMessagePackFormatter(); + private readonly MessagePackTimeOnlyVoMessagePackFormatter _timeOnlyVo = new MessagePackTimeOnlyVoMessagePackFormatter(); + private readonly FooFormatter _fooFormatter = new FooFormatter(); + private readonly MessagePackSerializerOptions _options; + + public MessagePackSerializationTests() + { + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [ + _fooFormatter, + _boolVo, + _floatVo, + _byteVo, + _charVo, + _dateOnlyVo, + _dateTimeOffsetVo, + _dateTimeVo, + _decimalVo, + _doubleVo, + _fooVo, + _guidVo, + _intVo, + _longVo, + _shortVo, + _stringVo, + _timeOnlyVo + ], + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + _options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + } + + [Fact] + public void RoundTrip_Bool() + { + var vo = MessagePackBoolVo.From(true); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + MessagePackBoolVo deserialised = MessagePackSerializer.Deserialize(mp, _options); + + vo.Value.Should().Be(deserialised.Value); + } + + [Fact] + public void RoundTrip_Byte() + { + byte value = 123; + var vo = MessagePackByteVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Char() + { + char value = 'a'; + var vo = MessagePackCharVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip() + { + var value = "ABC"; + var vo = MessagePackStringVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTimeOffset() + { + var vo = MessagePackDateTimeOffsetVo.From(Primitives.DateTimeOffset1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTime() + { + var vo = MessagePackDateTimeVo.From(Primitives.DateTime1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Decimal() + { + var vo = MessagePackDecimalVo.From(123.45m); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Double() + { + var vo = MessagePackDoubleVo.From(123.45d); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Float() + { + var vo = MessagePackFloatVo.From(123.45f); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123.45f); + } + + [Fact] + public void RoundTrip_Guid() + { + var vo = MessagePackGuidVo.From(Primitives.Guid1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Guid1); + } + + [Fact] + public void RoundTrip_Int() + { + var vo = MessagePackLongVo.From(123L); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_ShortMessagePackProvider() + { + var vo = MessagePackShortVo.From(123); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_String() + { + var vo = MessagePackStringVo.From("aaa"); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be("aaa"); + } + + [Fact] + public void RoundTrip_TimeOnly() + { + var vo = MessagePackTimeOnlyVo.From(Primitives.Time1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Time1); + } + + [Fact] + public void RoundTrip_Foo() + { + var vo = MessagePackFooVo.From(new Bar(42, "Fred")); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Age.Should().Be(42); + deserializedVo.Value.Name.Should().Be("Fred"); + } +} \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/FooVo.cs b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/FooVo.cs index a62b1eebc2..b8176c4f17 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/FooVo.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/FooVo.cs @@ -1,7 +1,5 @@ namespace Vogen.IntegrationTests.TestTypes.ClassVos; -public record struct Bar(int Age, string Name); - [ValueObject(conversions: Conversions.None, underlyingType: typeof(Bar))] public partial class FooVo { } diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/MessagePackTypes.cs b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/MessagePackTypes.cs new file mode 100644 index 0000000000..cc22a2705b --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/ClassVos/Types/MessagePackTypes.cs @@ -0,0 +1,49 @@ +namespace Vogen.IntegrationTests.TestTypes.ClassVos; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackBoolVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackFloatVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackByteVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackCharVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackDateOnlyVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackDateTimeOffsetVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackDateTimeVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackDecimalVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackDoubleVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackFooVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackGuidVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackIntVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackLongVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackShortVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackStringVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial class MessagePackTimeOnlyVo; \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs index 8f8bbfd53a..f2ab7ffe6b 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs @@ -1,6 +1,10 @@ #nullable disable +using MessagePack; using ServiceStack.Text; +using Vogen.IntegrationTests.TestTypes; +// ReSharper disable InconsistentNaming + // ReSharper disable FunctionComplexityOverflow namespace MediumTests.SerializationAndConversionTests; @@ -9,64 +13,487 @@ public partial class ComplexSerializationTests { public class ComplexServiceStackDotText { - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo.From(true); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo.From(1); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo.From('2'); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo.From(3.33m); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo.From(4.44d); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo.From(new Vogen.IntegrationTests.TestTypes.ClassVos.Bar(42, "Fred")); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo.From(Guid.Empty); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo.From(6); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo.From(7L); - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtStringVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("8"); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_ServiceStackTextJsonStringVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("9"); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo.From(true); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo.From(1); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo.From('2'); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo.From(3.33m); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo.From(4.44d); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo.From(new Vogen.IntegrationTests.TestTypes.RecordClassVos.Bar(42, "Fred")); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo.From(Guid.Empty); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo.From(6); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo.From(7L); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo.From(true); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo.From(1); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo.From('2'); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo.From(3.33m); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo.From(4.44d); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo.From(5.55f); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo.From(new Vogen.IntegrationTests.TestTypes.StructVos.Bar(42, "Fred")); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo.From(Guid.Empty); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo.From(6); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo.From(7L); - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtStringVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo.From("8"); - - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo.From(true); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo.From(1); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo.From('2'); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo.From(3.33m); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo.From(4.44d); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo.From(5.55f); - - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo.From(new Vogen.IntegrationTests.TestTypes.RecordStructVos.Bar(42, "Fred")); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo.From(Guid.Empty); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo.From(6); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo.From(7L); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo.From("8"); + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo + Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("8"); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_ServiceStackTextJsonStringVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("9"); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtIntVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtLongVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo.From("8"); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtIntVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo.From("8"); + } + + [MessagePackObject] + public class ComplexMessagePack + { + [Key(0)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackBoolVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackBoolVo.From(true); + + [Key(1)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackByteVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackByteVo.From(1); + + [Key(2)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackCharVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackCharVo.From('2'); + + [Key(3)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + [Key(4)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + [Key(5)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDecimalVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDecimalVo.From(3.33m); + + [Key(6)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDoubleVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDoubleVo.From(4.44d); + + [Key(7)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFloatVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFloatVo.From(5.55f); + + [Key(8)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFooVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFooVo.From(new Bar(42, "Fred")); + + [Key(9)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackGuidVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackGuidVo.From(Guid.Empty); + + [Key(10)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackIntVo Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackIntVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackIntVo.From(6); + + [Key(11)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackLongVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackLongVo.From(7L); + + [Key(12)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVo + Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVo.From("8"); + + [Key(13)] + public Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVo + Vogen_IntegrationTests_TestTypes_ClassVos_ServiceStackTextJsonStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVo.From("9"); + + [Key(14)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackBoolVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackBoolVo.From(true); + + [Key(15)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackByteVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackByteVo.From(1); + + [Key(16)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackCharVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackCharVo.From('2'); + + [Key(17)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, + 999, TimeSpan.Zero)); + + [Key(18)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + [Key(19)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDecimalVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDecimalVo.From(3.33m); + + [Key(20)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDoubleVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDoubleVo.From(4.44d); + + [Key(21)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFloatVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFloatVo.From(5.55f); + + [Key(22)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFooVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFooVo.From(new Bar(42, "Fred")); + + [Key(23)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackGuidVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackGuidVo.From(Guid.Empty); + + [Key(24)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackIntVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackIntVo.From(6); + + [Key(25)] + public Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackLongVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackLongVo.From(7L); + + [Key(26)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackBoolVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackBoolVo.From(true); + + [Key(27)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackByteVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackByteVo.From(1); + + [Key(28)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackCharVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackCharVo.From('2'); + + [Key(29)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + [Key(30)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + [Key(31)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDecimalVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDecimalVo.From(3.33m); + + [Key(32)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDoubleVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDoubleVo.From(4.44d); + + [Key(33)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFloatVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFloatVo.From(5.55f); + + [Key(34)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFooVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFooVo.From(new Bar(42, "Fred")); + + [Key(35)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackGuidVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackGuidVo.From(Guid.Empty); + + [Key(36)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackIntVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackIntVo.From(6); + + [Key(37)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackLongVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackLongVo.From(7L); + + [Key(38)] + public Vogen.IntegrationTests.TestTypes.StructVos.MessagePackStringVo + Vogen_IntegrationTests_TestTypes_StructVos_MessagePackStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.MessagePackStringVo.From("8"); + + [Key(39)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackBoolVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackBoolVo.From(true); + + [Key(40)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackByteVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackByteVo.From(1); + + [Key(41)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackCharVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackCharVo.From('2'); + + [Key(42)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, + 999, TimeSpan.Zero)); + + [Key(43)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + [Key(44)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDecimalVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDecimalVo.From(3.33m); + + [Key(45)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDoubleVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDoubleVo.From(4.44d); + + [Key(46)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFloatVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFloatVo.From(5.55f); + + [Key(47)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFooVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFooVo.From(new Bar(42, "Fred")); + + [Key(48)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackGuidVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackGuidVo.From(Guid.Empty); + + [Key(49)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackIntVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackIntVo.From(6); + + [Key(50)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackLongVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackLongVo.From(7L); + + [Key(51)] + public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVo.From("8"); } [Fact] @@ -81,8 +508,10 @@ public void Ssdt_CanSerializeAndDeserialize() deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo.Value.Should().Be(true); deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo.Value.Should().Be(1); deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo.Value.Should().Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo.Value.Should().Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo.Value.Should().Be(3.33m); deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo.Value.Should().Be(4.44d); deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo.Value.Should().Be(5.55f); @@ -97,8 +526,10 @@ public void Ssdt_CanSerializeAndDeserialize() deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo.Value.Should().Be(true); deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo.Value.Should().Be(1); deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo.Value.Should().Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo.Value.Should().Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo.Value.Should().Be(3.33m); deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo.Value.Should().Be(4.44d); deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo.Value.Should().Be(5.55f); @@ -111,8 +542,10 @@ public void Ssdt_CanSerializeAndDeserialize() deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo.Value.Should().Be(true); deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo.Value.Should().Be(1); deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo.Value.Should().Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo.Value.Should().Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo.Value.Should().Be(3.33m); deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo.Value.Should().Be(4.44d); deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo.Value.Should().Be(5.55f); @@ -126,8 +559,10 @@ public void Ssdt_CanSerializeAndDeserialize() deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo.Value.Should().Be(true); deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo.Value.Should().Be(1); deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo.Value.Should().Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo.Value.Should().Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo.Value.Should().Be(3.33m); deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo.Value.Should().Be(4.44d); deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo.Value.Should().Be(5.55f); @@ -138,4 +573,162 @@ public void Ssdt_CanSerializeAndDeserialize() deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo.Value.Should().Be(7L); deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo.Value.Should().Be("8"); } + + [Fact] + public void MessagePack_CanSerializeAndDeserialize() + { + ConsumerTests.SerializationAndConversionTests.FooFormatter fooFormatter = new(); + + + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [ + fooFormatter, + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackTimeOnlyVoMessagePackFormatter(), + + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackTimeOnlyVoMessagePackFormatter(), + + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackTimeOnlyVoMessagePackFormatter(), + + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackTimeOnlyVoMessagePackFormatter() + ], + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + + var complex = new ComplexMessagePack(); + + var mp = MessagePackSerializer.Serialize(complex, options); + + var deserialized = MessagePackSerializer.Deserialize(mp, options); + + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackStringVo.Value.Should().Be("8"); + + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackLongVo.Value.Should().Be(7L); + + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackStringVo.Value.Should().Be("8"); + + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackStringVo.Value.Should().Be("8"); + } } \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs index dc29564a75..9df78ea2b8 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs @@ -1,5 +1,6 @@ #nullable disable using ConsumerTests; +using Vogen.IntegrationTests.TestTypes; // ReSharper disable FunctionComplexityOverflow @@ -109,7 +110,7 @@ public class ComplexBson public Vogen.IntegrationTests.TestTypes.StructVos.BsonFloatVo ClassVos_BsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo ClassVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo.From(new Vogen.IntegrationTests.TestTypes.StructVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo ClassVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.StructVos.BsonGuidVo ClassVos_BsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonGuidVo.From(Guid.Empty); @@ -148,7 +149,7 @@ public class ComplexBson public Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonFloatVo RecordClassVos_BsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonFooVo RecordClassVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonFooVo.From(new Vogen.IntegrationTests.TestTypes.RecordClassVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonFooVo RecordClassVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonGuidVo RecordClassVos_BsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.BsonGuidVo.From(Guid.Empty); @@ -185,7 +186,7 @@ public class ComplexBson public Vogen.IntegrationTests.TestTypes.StructVos.BsonFloatVo StructVos_BsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo StructVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo.From(new Vogen.IntegrationTests.TestTypes.StructVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo StructVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.StructVos.BsonGuidVo StructVos_BsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.BsonGuidVo.From(Guid.Empty); @@ -224,7 +225,7 @@ public class ComplexBson public Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonFloatVo RecordStructVos_BsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonFooVo RecordStructVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonFooVo.From(new Vogen.IntegrationTests.TestTypes.RecordStructVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonFooVo RecordStructVos_BsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonGuidVo RecordStructVos_BsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.BsonGuidVo.From(Guid.Empty); diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs index 0df3520dc9..a5099b2fa2 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs @@ -1,5 +1,7 @@ #nullable disable using System.Text.Json; +using Vogen.IntegrationTests.TestTypes; + // ReSharper disable FunctionComplexityOverflow namespace MediumTests.SerializationAndConversionTests; @@ -16,7 +18,7 @@ public class ComplexSystemTextJson public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonDecimalVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonDecimalVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonDecimalVo.From(3.33m); public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonDoubleVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonDoubleVo.From(4.44d); public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonFloatVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonFooVo.From(new Vogen.IntegrationTests.TestTypes.ClassVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonGuidVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonGuidVo.From(Guid.Empty); public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonIntVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonIntVo.From(6); public Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonLongVo Vogen_IntegrationTests_TestTypes_ClassVos_SystemTextJsonLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.ClassVos.SystemTextJsonLongVo.From(7L); @@ -32,7 +34,7 @@ public class ComplexSystemTextJson public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonDecimalVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonDecimalVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonDecimalVo.From(3.33m); public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonDoubleVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonDoubleVo.From(4.44d); public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonFloatVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonFooVo.From(new Vogen.IntegrationTests.TestTypes.RecordClassVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonGuidVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonGuidVo.From(Guid.Empty); public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonIntVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonIntVo.From(6); public Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonLongVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SystemTextJsonLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SystemTextJsonLongVo.From(7L); @@ -46,7 +48,7 @@ public class ComplexSystemTextJson public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonDoubleVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonDoubleVo.From(4.44d); public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonFloatVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonFooVo.From(new Vogen.IntegrationTests.TestTypes.StructVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonGuidVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonGuidVo.From(Guid.Empty); public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonIntVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonIntVo.From(6); public Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonLongVo Vogen_IntegrationTests_TestTypes_StructVos_SystemTextJsonLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.StructVos.SystemTextJsonLongVo.From(7L); @@ -61,7 +63,7 @@ public class ComplexSystemTextJson public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonDoubleVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonDoubleVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonDoubleVo.From(4.44d); public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonFloatVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonFloatVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonFloatVo.From(5.55f); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonFooVo.From(new Vogen.IntegrationTests.TestTypes.RecordStructVos.Bar(42, "Fred")); + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonFooVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonFooVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonFooVo.From(new Bar(42, "Fred")); public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonGuidVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonGuidVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonGuidVo.From(Guid.Empty); public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonIntVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonIntVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonIntVo.From(6); public Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonLongVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SystemTextJsonLongVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SystemTextJsonLongVo.From(7L); diff --git a/tests/ConsumerTests/SerializationAndConversionTests/FooFormatter.cs b/tests/ConsumerTests/SerializationAndConversionTests/FooFormatter.cs new file mode 100644 index 0000000000..d5cfa6609b --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/FooFormatter.cs @@ -0,0 +1,26 @@ +using MessagePack; +using MessagePack.Formatters; +using Vogen.IntegrationTests.TestTypes; + +namespace ConsumerTests.SerializationAndConversionTests; + +public class FooFormatter : IMessagePackFormatter +{ + public Bar Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + var age = reader.ReadInt32(); + var name = reader.ReadString(); + + return new Bar + { + Age = age, + Name = name! + }; + } + + public void Serialize(ref MessagePackWriter writer, Bar value, MessagePackSerializerOptions options) + { + writer.Write(value.Age); + writer.Write(value.Name); + } +} \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/AnyOtherTypeVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/AnyOtherTypeVoTests.cs index dfd4ad6780..5d40310b83 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/AnyOtherTypeVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/AnyOtherTypeVoTests.cs @@ -9,6 +9,7 @@ using LinqToDB.Mapping; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Vogen.IntegrationTests.TestTypes; using Vogen.IntegrationTests.TestTypes.RecordClassVos; using NewtonsoftJsonSerializer = Newtonsoft.Json.JsonConvert; using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs new file mode 100644 index 0000000000..1ae798efb3 --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs @@ -0,0 +1,256 @@ +using ConsumerTests.BugFixTests; +using MessagePack; +using MessagePack.Formatters; +using Vogen.IntegrationTests.TestTypes; +using Vogen.IntegrationTests.TestTypes.RecordClassVos; +using Bar = Vogen.IntegrationTests.TestTypes.Bar; + +// ReSharper disable NullableWarningSuppressionIsUsed + +namespace ConsumerTests.SerializationAndConversionTests.RecordClassVos; + +public class MessagePackSerializationTests +{ + public class FooFormatter : IMessagePackFormatter + { + public Bar Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + var age = reader.ReadInt32(); + var name = reader.ReadString(); + + return new Bar + { + Age = age, + Name = name! + }; + } + + public void Serialize(ref MessagePackWriter writer, Bar value, MessagePackSerializerOptions options) + { + writer.Write(value.Age); + writer.Write(value.Name); + } + } + + private readonly MessagePackBoolVoMessagePackFormatter _boolVo = new MessagePackBoolVoMessagePackFormatter(); + private readonly MessagePackFloatVoMessagePackFormatter _floatVo = new MessagePackFloatVoMessagePackFormatter(); + private readonly MessagePackByteVoMessagePackFormatter _byteVo = new MessagePackByteVoMessagePackFormatter(); + private readonly MessagePackCharVoMessagePackFormatter _charVo = new MessagePackCharVoMessagePackFormatter(); + private readonly MessagePackDateOnlyVoMessagePackFormatter _dateOnlyVo = new MessagePackDateOnlyVoMessagePackFormatter(); + + private readonly MessagePackDateTimeOffsetVoMessagePackFormatter _dateTimeOffsetVo = + new MessagePackDateTimeOffsetVoMessagePackFormatter(); + + private readonly MessagePackDateTimeVoMessagePackFormatter _dateTimeVo = new MessagePackDateTimeVoMessagePackFormatter(); + private readonly MessagePackDecimalVoMessagePackFormatter _decimalVo = new MessagePackDecimalVoMessagePackFormatter(); + private readonly MessagePackDoubleVoMessagePackFormatter _doubleVo = new MessagePackDoubleVoMessagePackFormatter(); + private readonly MessagePackFooVoMessagePackFormatter _fooVo = new MessagePackFooVoMessagePackFormatter(); + private readonly MessagePackGuidVoMessagePackFormatter _guidVo = new MessagePackGuidVoMessagePackFormatter(); + private readonly MessagePackIntVoMessagePackFormatter _intVo = new MessagePackIntVoMessagePackFormatter(); + private readonly MessagePackLongVoMessagePackFormatter _longVo = new MessagePackLongVoMessagePackFormatter(); + private readonly MessagePackShortVoMessagePackFormatter _shortVo = new MessagePackShortVoMessagePackFormatter(); + private readonly MessagePackStringVoMessagePackFormatter _stringVo = new MessagePackStringVoMessagePackFormatter(); + private readonly MessagePackTimeOnlyVoMessagePackFormatter _timeOnlyVo = new MessagePackTimeOnlyVoMessagePackFormatter(); + private readonly FooFormatter _fooFormatter = new FooFormatter(); + private readonly MessagePackSerializerOptions _options; + + public MessagePackSerializationTests() + { + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [ + _fooFormatter, + _boolVo, + _floatVo, + _byteVo, + _charVo, + _dateOnlyVo, + _dateTimeOffsetVo, + _dateTimeVo, + _decimalVo, + _doubleVo, + _fooVo, + _guidVo, + _intVo, + _longVo, + _shortVo, + _stringVo, + _timeOnlyVo + ], + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + _options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + } + + [Fact] + public void RoundTrip_Bool() + { + var vo = MessagePackBoolVo.From(true); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + MessagePackBoolVo deserialised = MessagePackSerializer.Deserialize(mp, _options); + + vo.Value.Should().Be(deserialised.Value); + } + + [Fact] + public void RoundTrip_Byte() + { + byte value = 123; + var vo = MessagePackByteVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Char() + { + char value = 'a'; + var vo = MessagePackCharVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip() + { + var value = "ABC"; + var vo = MessagePackStringVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTimeOffset() + { + var vo = MessagePackDateTimeOffsetVo.From(Primitives.DateTimeOffset1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTime() + { + var vo = MessagePackDateTimeVo.From(Primitives.DateTime1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Decimal() + { + var vo = MessagePackDecimalVo.From(123.45m); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Double() + { + var vo = MessagePackDoubleVo.From(123.45d); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Float() + { + var vo = MessagePackFloatVo.From(123.45f); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123.45f); + } + + [Fact] + public void RoundTrip_Guid() + { + var vo = MessagePackGuidVo.From(Primitives.Guid1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Guid1); + } + + [Fact] + public void RoundTrip_Int() + { + var vo = MessagePackLongVo.From(123L); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_ShortMessagePackProvider() + { + var vo = MessagePackShortVo.From(123); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_String() + { + var vo = MessagePackStringVo.From("aaa"); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be("aaa"); + } + + [Fact] + public void RoundTrip_TimeOnly() + { + var vo = MessagePackTimeOnlyVo.From(Primitives.Time1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Time1); + } + + [Fact] + public void RoundTrip_Foo() + { + var vo = MessagePackFooVo.From(new Bar(42, "Fred")); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Age.Should().Be(42); + deserializedVo.Value.Name.Should().Be("Fred"); + } +} \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/FooVo.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/FooVo.cs index 0e928c3f8b..1087a65786 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/FooVo.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/FooVo.cs @@ -1,7 +1,5 @@ namespace Vogen.IntegrationTests.TestTypes.RecordClassVos; -public record struct Bar(int Age, string Name); - [ValueObject(conversions: Conversions.None, underlyingType: typeof(Bar))] public partial record class FooVo { } diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/MessagePackTypes.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/MessagePackTypes.cs new file mode 100644 index 0000000000..ed487e8f25 --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/Types/MessagePackTypes.cs @@ -0,0 +1,49 @@ +namespace Vogen.IntegrationTests.TestTypes.RecordClassVos; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackBoolVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackFloatVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackByteVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackCharVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackDateOnlyVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackDateTimeOffsetVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackDateTimeVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackDecimalVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackDoubleVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackFooVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackGuidVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackIntVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackLongVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackShortVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackStringVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record class MessagePackTimeOnlyVo; \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/AnyOtherTypeVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/AnyOtherTypeVoTests.cs index 49b9b9181d..afca94dde9 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/AnyOtherTypeVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/AnyOtherTypeVoTests.cs @@ -9,6 +9,7 @@ using LinqToDB.Mapping; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Vogen.IntegrationTests.TestTypes; using Vogen.IntegrationTests.TestTypes.RecordStructVos; using NewtonsoftJsonSerializer = Newtonsoft.Json.JsonConvert; using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs new file mode 100644 index 0000000000..095fa36f9c --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs @@ -0,0 +1,256 @@ +using ConsumerTests.BugFixTests; +using MessagePack; +using MessagePack.Formatters; +using Vogen.IntegrationTests.TestTypes; +using Vogen.IntegrationTests.TestTypes.RecordStructVos; +using Bar = Vogen.IntegrationTests.TestTypes.Bar; + +// ReSharper disable NullableWarningSuppressionIsUsed + +namespace ConsumerTests.SerializationAndConversionTests.RecordStructVos; + +public class MessagePackSerializationTests +{ + public class FooFormatter : IMessagePackFormatter + { + public Bar Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + var age = reader.ReadInt32(); + var name = reader.ReadString(); + + return new Bar + { + Age = age, + Name = name! + }; + } + + public void Serialize(ref MessagePackWriter writer, Bar value, MessagePackSerializerOptions options) + { + writer.Write(value.Age); + writer.Write(value.Name); + } + } + + private readonly MessagePackBoolVoMessagePackFormatter _boolVo = new MessagePackBoolVoMessagePackFormatter(); + private readonly MessagePackFloatVoMessagePackFormatter _floatVo = new MessagePackFloatVoMessagePackFormatter(); + private readonly MessagePackByteVoMessagePackFormatter _byteVo = new MessagePackByteVoMessagePackFormatter(); + private readonly MessagePackCharVoMessagePackFormatter _charVo = new MessagePackCharVoMessagePackFormatter(); + private readonly MessagePackDateOnlyVoMessagePackFormatter _dateOnlyVo = new MessagePackDateOnlyVoMessagePackFormatter(); + + private readonly MessagePackDateTimeOffsetVoMessagePackFormatter _dateTimeOffsetVo = + new MessagePackDateTimeOffsetVoMessagePackFormatter(); + + private readonly MessagePackDateTimeVoMessagePackFormatter _dateTimeVo = new MessagePackDateTimeVoMessagePackFormatter(); + private readonly MessagePackDecimalVoMessagePackFormatter _decimalVo = new MessagePackDecimalVoMessagePackFormatter(); + private readonly MessagePackDoubleVoMessagePackFormatter _doubleVo = new MessagePackDoubleVoMessagePackFormatter(); + private readonly MessagePackFooVoMessagePackFormatter _fooVo = new MessagePackFooVoMessagePackFormatter(); + private readonly MessagePackGuidVoMessagePackFormatter _guidVo = new MessagePackGuidVoMessagePackFormatter(); + private readonly MessagePackIntVoMessagePackFormatter _intVo = new MessagePackIntVoMessagePackFormatter(); + private readonly MessagePackLongVoMessagePackFormatter _longVo = new MessagePackLongVoMessagePackFormatter(); + private readonly MessagePackShortVoMessagePackFormatter _shortVo = new MessagePackShortVoMessagePackFormatter(); + private readonly MessagePackStringVoMessagePackFormatter _stringVo = new MessagePackStringVoMessagePackFormatter(); + private readonly MessagePackTimeOnlyVoMessagePackFormatter _timeOnlyVo = new MessagePackTimeOnlyVoMessagePackFormatter(); + private readonly FooFormatter _fooFormatter = new FooFormatter(); + private readonly MessagePackSerializerOptions _options; + + public MessagePackSerializationTests() + { + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [ + _fooFormatter, + _boolVo, + _floatVo, + _byteVo, + _charVo, + _dateOnlyVo, + _dateTimeOffsetVo, + _dateTimeVo, + _decimalVo, + _doubleVo, + _fooVo, + _guidVo, + _intVo, + _longVo, + _shortVo, + _stringVo, + _timeOnlyVo + ], + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + _options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + } + + [Fact] + public void RoundTrip_Bool() + { + var vo = MessagePackBoolVo.From(true); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + MessagePackBoolVo deserialised = MessagePackSerializer.Deserialize(mp, _options); + + vo.Value.Should().Be(deserialised.Value); + } + + [Fact] + public void RoundTrip_Byte() + { + byte value = 123; + var vo = MessagePackByteVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Char() + { + char value = 'a'; + var vo = MessagePackCharVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip() + { + var value = "ABC"; + var vo = MessagePackStringVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTimeOffset() + { + var vo = MessagePackDateTimeOffsetVo.From(Primitives.DateTimeOffset1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTime() + { + var vo = MessagePackDateTimeVo.From(Primitives.DateTime1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Decimal() + { + var vo = MessagePackDecimalVo.From(123.45m); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Double() + { + var vo = MessagePackDoubleVo.From(123.45d); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Float() + { + var vo = MessagePackFloatVo.From(123.45f); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123.45f); + } + + [Fact] + public void RoundTrip_Guid() + { + var vo = MessagePackGuidVo.From(Primitives.Guid1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Guid1); + } + + [Fact] + public void RoundTrip_Int() + { + var vo = MessagePackLongVo.From(123L); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_ShortMessagePackProvider() + { + var vo = MessagePackShortVo.From(123); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_String() + { + var vo = MessagePackStringVo.From("aaa"); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be("aaa"); + } + + [Fact] + public void RoundTrip_TimeOnly() + { + var vo = MessagePackTimeOnlyVo.From(Primitives.Time1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Time1); + } + + [Fact] + public void RoundTrip_Foo() + { + var vo = MessagePackFooVo.From(new Bar(42, "Fred")); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Age.Should().Be(42); + deserializedVo.Value.Name.Should().Be("Fred"); + } +} \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/FooVo.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/FooVo.cs index 6f572c28e0..491a3f1723 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/FooVo.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/FooVo.cs @@ -1,7 +1,5 @@ namespace Vogen.IntegrationTests.TestTypes.RecordStructVos; -public record struct Bar(int Age, string Name); - [ValueObject(conversions: Conversions.None, underlyingType: typeof(Bar))] public partial record struct FooVo { } diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/MessagePackTypes.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/MessagePackTypes.cs new file mode 100644 index 0000000000..c516dca965 --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/Types/MessagePackTypes.cs @@ -0,0 +1,49 @@ +namespace Vogen.IntegrationTests.TestTypes.RecordStructVos; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackBoolVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackFloatVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackByteVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackCharVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackDateOnlyVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackDateTimeOffsetVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackDateTimeVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackDecimalVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackDoubleVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackFooVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackGuidVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackIntVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackLongVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackShortVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackStringVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial record struct MessagePackTimeOnlyVo; \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/AnyOtherTypeVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/AnyOtherTypeVoTests.cs index 5a5b71ab49..8fa22084a7 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/AnyOtherTypeVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/AnyOtherTypeVoTests.cs @@ -9,6 +9,7 @@ using LinqToDB.Mapping; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Vogen.IntegrationTests.TestTypes; using Vogen.IntegrationTests.TestTypes.StructVos; using NewtonsoftJsonSerializer = Newtonsoft.Json.JsonConvert; using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs new file mode 100644 index 0000000000..b4d87dbe5e --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs @@ -0,0 +1,256 @@ +using ConsumerTests.BugFixTests; +using MessagePack; +using MessagePack.Formatters; +using Vogen.IntegrationTests.TestTypes; +using Vogen.IntegrationTests.TestTypes.StructVos; +using Bar = Vogen.IntegrationTests.TestTypes.Bar; + +// ReSharper disable NullableWarningSuppressionIsUsed + +namespace ConsumerTests.SerializationAndConversionTests.StructVos; + +public class MessagePackSerializationTests +{ + public class FooFormatter : IMessagePackFormatter + { + public Bar Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) + { + var age = reader.ReadInt32(); + var name = reader.ReadString(); + + return new Bar + { + Age = age, + Name = name! + }; + } + + public void Serialize(ref MessagePackWriter writer, Bar value, MessagePackSerializerOptions options) + { + writer.Write(value.Age); + writer.Write(value.Name); + } + } + + private readonly MessagePackBoolVoMessagePackFormatter _boolVo = new MessagePackBoolVoMessagePackFormatter(); + private readonly MessagePackFloatVoMessagePackFormatter _floatVo = new MessagePackFloatVoMessagePackFormatter(); + private readonly MessagePackByteVoMessagePackFormatter _byteVo = new MessagePackByteVoMessagePackFormatter(); + private readonly MessagePackCharVoMessagePackFormatter _charVo = new MessagePackCharVoMessagePackFormatter(); + private readonly MessagePackDateOnlyVoMessagePackFormatter _dateOnlyVo = new MessagePackDateOnlyVoMessagePackFormatter(); + + private readonly MessagePackDateTimeOffsetVoMessagePackFormatter _dateTimeOffsetVo = + new MessagePackDateTimeOffsetVoMessagePackFormatter(); + + private readonly MessagePackDateTimeVoMessagePackFormatter _dateTimeVo = new MessagePackDateTimeVoMessagePackFormatter(); + private readonly MessagePackDecimalVoMessagePackFormatter _decimalVo = new MessagePackDecimalVoMessagePackFormatter(); + private readonly MessagePackDoubleVoMessagePackFormatter _doubleVo = new MessagePackDoubleVoMessagePackFormatter(); + private readonly MessagePackFooVoMessagePackFormatter _fooVo = new MessagePackFooVoMessagePackFormatter(); + private readonly MessagePackGuidVoMessagePackFormatter _guidVo = new MessagePackGuidVoMessagePackFormatter(); + private readonly MessagePackIntVoMessagePackFormatter _intVo = new MessagePackIntVoMessagePackFormatter(); + private readonly MessagePackLongVoMessagePackFormatter _longVo = new MessagePackLongVoMessagePackFormatter(); + private readonly MessagePackShortVoMessagePackFormatter _shortVo = new MessagePackShortVoMessagePackFormatter(); + private readonly MessagePackStringVoMessagePackFormatter _stringVo = new MessagePackStringVoMessagePackFormatter(); + private readonly MessagePackTimeOnlyVoMessagePackFormatter _timeOnlyVo = new MessagePackTimeOnlyVoMessagePackFormatter(); + private readonly FooFormatter _fooFormatter = new FooFormatter(); + private readonly MessagePackSerializerOptions _options; + + public MessagePackSerializationTests() + { + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [ + _fooFormatter, + _boolVo, + _floatVo, + _byteVo, + _charVo, + _dateOnlyVo, + _dateTimeOffsetVo, + _dateTimeVo, + _decimalVo, + _doubleVo, + _fooVo, + _guidVo, + _intVo, + _longVo, + _shortVo, + _stringVo, + _timeOnlyVo + ], + [MessagePack.Resolvers.StandardResolver.Instance] + ); + + _options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); + } + + [Fact] + public void RoundTrip_Bool() + { + var vo = MessagePackBoolVo.From(true); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + MessagePackBoolVo deserialised = MessagePackSerializer.Deserialize(mp, _options); + + vo.Value.Should().Be(deserialised.Value); + } + + [Fact] + public void RoundTrip_Byte() + { + byte value = 123; + var vo = MessagePackByteVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Char() + { + char value = 'a'; + var vo = MessagePackCharVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip() + { + var value = "ABC"; + var vo = MessagePackStringVo.From(value); + var mp = MessagePackSerializer.Serialize(value, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTimeOffset() + { + var vo = MessagePackDateTimeOffsetVo.From(Primitives.DateTimeOffset1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_DateTime() + { + var vo = MessagePackDateTimeVo.From(Primitives.DateTime1); + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Decimal() + { + var vo = MessagePackDecimalVo.From(123.45m); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Double() + { + var vo = MessagePackDoubleVo.From(123.45d); + + var mp = MessagePackSerializer.Serialize(vo, _options); + + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + Assert.Equal(vo, deserializedVo); + } + + [Fact] + public void RoundTrip_Float() + { + var vo = MessagePackFloatVo.From(123.45f); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123.45f); + } + + [Fact] + public void RoundTrip_Guid() + { + var vo = MessagePackGuidVo.From(Primitives.Guid1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Guid1); + } + + [Fact] + public void RoundTrip_Int() + { + var vo = MessagePackLongVo.From(123L); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_ShortMessagePackProvider() + { + var vo = MessagePackShortVo.From(123); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(123); + } + + [Fact] + public void RoundTrip_String() + { + var vo = MessagePackStringVo.From("aaa"); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be("aaa"); + } + + [Fact] + public void RoundTrip_TimeOnly() + { + var vo = MessagePackTimeOnlyVo.From(Primitives.Time1); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Should().Be(Primitives.Time1); + } + + [Fact] + public void RoundTrip_Foo() + { + var vo = MessagePackFooVo.From(new Bar(42, "Fred")); + + var mp = MessagePackSerializer.Serialize(vo, _options); + var deserializedVo = MessagePackSerializer.Deserialize(mp, _options); + + deserializedVo.Value.Age.Should().Be(42); + deserializedVo.Value.Name.Should().Be("Fred"); + } +} \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/StringVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/StringVoTests.cs index bf66c26ee9..a80b7fd574 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/StringVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/StringVoTests.cs @@ -12,6 +12,10 @@ using LinqToDB.Data; using LinqToDB.DataProvider.SQLite; using LinqToDB.Mapping; +// ReSharper disable EqualExpressionComparison +// ReSharper disable RedundantCast +// ReSharper disable SuspiciousTypeConversion.Global +// ReSharper disable NullableWarningSuppressionIsUsed namespace Vogen.IntegrationTests.SerializationAndConversionTests.StructVos; @@ -40,10 +44,8 @@ public void equality_between_same_value_objects() } [Fact] - public void equality_between_different_value_objects() - { + public void equality_between_different_value_objects() => StringVo.From("hello!").Equals(AnotherStringVo.From("hello!")).Should().BeFalse(); - } [Fact] public void CanSerializeToString_WithNewtonsoftJsonProvider() @@ -172,7 +174,7 @@ public void WhenEfCoreValueConverterUsesValueConverter() [Fact] public async Task WhenDapperValueConverterUsesValueConverter() { - using var connection = new SqliteConnection("DataSource=:memory:"); + await using var connection = new SqliteConnection("DataSource=:memory:"); await connection.OpenAsync(); IEnumerable results = await connection.QueryAsync("SELECT 'foo!'"); @@ -215,7 +217,7 @@ public void TypeConverter_CanConvertToAndFrom(object value) var converter = TypeDescriptor.GetConverter(typeof(NoJsonStringVo)); var id = converter.ConvertFrom(value); Assert.IsType(id); - Assert.Equal(NoJsonStringVo.From(value!.ToString()), id); + Assert.Equal(NoJsonStringVo.From(value.ToString()!), id); var reconverted = converter.ConvertTo(id, value.GetType()); Assert.Equal(value, reconverted); diff --git a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/FooVo.cs b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/FooVo.cs index 38fa61f5dd..c0cefbb3c6 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/FooVo.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/FooVo.cs @@ -1,7 +1,5 @@ namespace Vogen.IntegrationTests.TestTypes.StructVos; -public record struct Bar(int Age, string Name); - [ValueObject(conversions: Conversions.None, underlyingType: typeof(Bar))] public partial struct FooVo { } diff --git a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/MessagePackTypes.cs b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/MessagePackTypes.cs new file mode 100644 index 0000000000..d03e071097 --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/Types/MessagePackTypes.cs @@ -0,0 +1,49 @@ +namespace Vogen.IntegrationTests.TestTypes.StructVos; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackBoolVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackFloatVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackByteVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackCharVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackDateOnlyVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackDateTimeOffsetVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackDateTimeVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackDecimalVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackDoubleVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackFooVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackGuidVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackIntVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackLongVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackShortVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackStringVo; + +[ValueObject(conversions: Conversions.MessagePack)] +public partial struct MessagePackTimeOnlyVo; \ No newline at end of file diff --git a/tests/Testbench/Program.cs b/tests/Testbench/Program.cs index 606582a606..bf0b5c9c26 100644 --- a/tests/Testbench/Program.cs +++ b/tests/Testbench/Program.cs @@ -1,6 +1,8 @@ using System; +using System.Linq; using MessagePack; using MessagePack.Formatters; +using MessagePack.Resolvers; using N1; using N2; using Vogen; @@ -12,6 +14,7 @@ namespace Testbench; [MessagePack()] [MessagePack()] [MessagePack()] +[MessagePack()] [MessagePack()] [EfCoreConverter] internal partial class MyMarkers; @@ -28,19 +31,21 @@ public static void Main() // Create an instance of the sample class var originalObject = new Sample { - Id = MyId.From(123), + Id = MyId.From(Guid.NewGuid()), Name = Name.From("Test"), + StartDate = StartDate.From(DateTimeOffset.Now), Active = MyBool.From(true) }; -// Caret is currently at line 47 - -// Create custom resolver with the MyIdFormatter + IMessagePackFormatter[] messagePackFormatters = MyMarkers.MessagePackFormatters; + +//messagePackFormatters = messagePackFormatters.Append(new MyGuidFormatter()).ToArray(); + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( - MyMarkers.MessagePackFormatters, + messagePackFormatters, // new IMessagePackFormatter[] { new MyMarkers.MyIdMessagePackFormatter(), new MyMarkers.NameMessagePackFormatter(), new MyMarkers.MyBoolMessagePackFormatter() }, - new IFormatterResolver[] { MessagePack.Resolvers.StandardResolver.Instance } + [MessagePack.Resolvers.StandardResolver.Instance] ); var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); @@ -52,11 +57,29 @@ public static void Main() var deserializedObject = MessagePackSerializer.Deserialize(serializedObject, options); // Display the deserialized object - Console.WriteLine($"Id: {deserializedObject.Id}, Name: {deserializedObject.Name}, Active: {deserializedObject.Active}"); + Console.WriteLine($"Id: {deserializedObject.Id}, Name: {deserializedObject.Name}, Active: {deserializedObject.Active}, StartDate: {deserializedObject.StartDate:o}"); } } +// public class MyGuidFormatter : IMessagePackFormatter +// { +// public void Serialize(ref MessagePackWriter writer, MyId value, MessagePackSerializerOptions options) +// { +// IMessagePackFormatter? r = StandardResolver.Instance.GetFormatter(); +// if (r is null) throw new MessagePackSerializationException(""); +// r.Serialize(ref writer, value.Value, options); +// } +// +// public MyId Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options) +// { +// IMessagePackFormatter? r = StandardResolver.Instance.GetFormatter(); +// if (r is null) throw new MessagePackSerializationException(""); +// Guid? g = r?.Deserialize(ref reader, options); +// +// return MyId.From(g!.Value); +// } +// } [MessagePackObject] public class Sample @@ -66,9 +89,13 @@ public class Sample [MessagePack.Key(1)] public Name Name { get; set; } = Name.From(""); [MessagePack.Key(2)] public MyBool Active { get; set; } = MyBool.From(false); + [MessagePack.Key(3)] public StartDate StartDate { get; set; } } -[ValueObject] +[ValueObject] +public partial struct StartDate; + +[ValueObject] public partial struct MyId; [ValueObject] From acd8d745ecdd181fbbebf02e7920b0df364ef4c4 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Wed, 13 Nov 2024 09:53:35 +0000 Subject: [PATCH 08/10] Tidy up and update snapshots --- Vogen.sln.DotSettings | 1 + samples/WebApplication/WebApplication.csproj | 2 +- .../WebApplicationConsumer.csproj | 2 +- src/Vogen/ConversionMarkers.cs | 6 +- src/Vogen/GenerateCodeForMessagePack.cs | 37 +- .../GenerateCodeForMessagePackMarkers.cs | 2 +- src/Vogen/MarkerAttributeDefinition.cs | 2 +- src/Vogen/ValueObjectGenerator.cs | 2 +- tests/ConsumerTests/BugFix624.cs | 5 - tests/ConsumerTests/BugFixTests/BugFix595.cs | 1 - tests/ConsumerTests/BugFixTests/BugFix624.cs | 3 - tests/ConsumerTests/CreationTests.cs | 2 - .../ComplexSerializationTests_Bson.cs | 2 +- ... ComplexSerializationTests_MessagePack.cs} | 577 +++++------------- ...xSerializationTests_ServiceStackDotText.cs | 300 +++++++++ ...ComplexSerializationTests_SytemTextJson.cs | 2 +- .../MessagePackSerializationTests.cs | 1 - .../RecordClassVos/StringVoTests.cs | 1 + .../MessagePackSerializationTests.cs | 1 - .../RecordStructVos/StringVoTests.cs | 7 +- .../MessagePackSerializationTests.cs | 1 - ...essagepack_and_efcore_markers.verified.txt | 5 + ...Generates_messagepack_markers.verified.txt | 5 + 23 files changed, 481 insertions(+), 486 deletions(-) rename tests/ConsumerTests/SerializationAndConversionTests/{ComplexSerializationTests.cs => ComplexSerializationTests_MessagePack.cs} (60%) create mode 100644 tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_ServiceStackDotText.cs diff --git a/Vogen.sln.DotSettings b/Vogen.sln.DotSettings index 276398dab3..64e597516b 100644 --- a/Vogen.sln.DotSettings +++ b/Vogen.sln.DotSettings @@ -32,6 +32,7 @@ True CHOP_IF_LONG UseVarWhenEvident + EF <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /></Policy> diff --git a/samples/WebApplication/WebApplication.csproj b/samples/WebApplication/WebApplication.csproj index 7de66fa6f2..e78130a272 100644 --- a/samples/WebApplication/WebApplication.csproj +++ b/samples/WebApplication/WebApplication.csproj @@ -19,7 +19,7 @@ - + diff --git a/samples/WebApplicationConsumer/WebApplicationConsumer.csproj b/samples/WebApplicationConsumer/WebApplicationConsumer.csproj index 61269b9bd3..22f0654f9c 100644 --- a/samples/WebApplicationConsumer/WebApplicationConsumer.csproj +++ b/samples/WebApplicationConsumer/WebApplicationConsumer.csproj @@ -11,7 +11,7 @@ - + diff --git a/src/Vogen/ConversionMarkers.cs b/src/Vogen/ConversionMarkers.cs index fcf7fb13ff..0e95005b9f 100644 --- a/src/Vogen/ConversionMarkers.cs +++ b/src/Vogen/ConversionMarkers.cs @@ -83,7 +83,7 @@ public static bool IsTarget(SyntaxNode node) => if (!VoFilter.IsTarget(voSymbol)) { // return ConversionMarkerAttributeDefinition.Error(markerKind, DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol)); - return MarkerAttributeDefinition.Error(markerKind, DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol)); + return MarkerAttributeDefinition.Error(DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol)); } List voAttributes = VoFilter.TryGetValueObjectAttributes(voSymbol).ToList(); @@ -102,9 +102,7 @@ public static bool IsTarget(SyntaxNode node) => if (underlyingType is null) { - return MarkerAttributeDefinition.Error( - markerKind, - DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol, markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation())); + return MarkerAttributeDefinition.Error(DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol, markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation())); } return MarkerAttributeDefinition.Ok(markerKind, voSymbol, underlyingType, markerClassSymbol!); diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs index 10f96fc95e..f8bc7efd72 100644 --- a/src/Vogen/GenerateCodeForMessagePack.cs +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -9,10 +9,7 @@ namespace Vogen; internal class GenerateCodeForMessagePack { - public static void GenerateForAMarkerClass(SourceProductionContext context, - Compilation compilation, - MarkerClassDefinition markerClass, - VogenKnownSymbols vogenKnownSymbols) + public static void GenerateForAMarkerClass(SourceProductionContext context, MarkerClassDefinition markerClass) { var markerClassSymbol = markerClass.MarkerClassSymbol; @@ -21,7 +18,7 @@ public static void GenerateForAMarkerClass(SourceProductionContext context, return; } - string pns = markerClassSymbol.FullNamespace() ?? ""; + string pns = markerClassSymbol.FullNamespace(); string ns = pns.Length == 0 ? "" : $"namespace {pns};"; @@ -66,10 +63,10 @@ string GenerateEach() m => m.Marker?.Kind is ConversionMarkerKind.MessagePack).Select( x => { - if (x is null) return null; + //if (x is null) return null; if (x.Marker is null) return null; - string? wrapperNameShort = x.Marker.VoSymbol.Name; + string wrapperNameShort = x.Marker.VoSymbol.Name; return $"new {wrapperNameShort}MessagePackFormatter()"; }).ToArray(); @@ -82,12 +79,12 @@ string GenerateFormatters() { StringBuilder sb = new(); - foreach (MarkerAttributeDefinition eachMarker in markerClass.AttributeDefinitions.Where( + foreach (MarkerAttributeDefinition eachAttr in markerClass.AttributeDefinitions.Where( m => m.Marker?.Kind is ConversionMarkerKind.MessagePack)) { sb.AppendLine( $$""" - {{GenerateSource("public", eachMarker.Marker!.VoSymbol, eachMarker.Marker.UnderlyingTypeSymbol, vogenKnownSymbols)}} + {{GenerateSource("public", eachAttr.Marker!.VoSymbol, eachAttr.Marker.UnderlyingTypeSymbol)}} """); } @@ -97,8 +94,7 @@ string GenerateFormatters() public static void GenerateForApplicableValueObjects(SourceProductionContext context, Compilation compilation, - List valueObjects, - VogenKnownSymbols knownSymbols) + List valueObjects) { if (!compilation.IsAtLeastCSharpVersion(LanguageVersion.CSharp12)) { @@ -110,7 +106,7 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con List items = matchingVos.Select(MessagePackStandalone.FromWorkItem).ToList(); List toWrite = items.Select( - p => GenerateSourceAndFilename(p.WrapperAccessibility, p.WrapperType, p.ContainerNamespace, p.UnderlyingType, knownSymbols)).ToList(); + p => GenerateSourceAndFilename(p.WrapperAccessibility, p.WrapperType, p.ContainerNamespace, p.UnderlyingType)).ToList(); foreach (var eachToWrite in toWrite) { @@ -120,16 +116,13 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con } } - public record FormatterSourceAndFilename(string FormatterFullyQualifiedName, string Filename, string SourceCode); + private record FormatterSourceAndFilename(string Filename, string SourceCode); private static FormatterSourceAndFilename GenerateSourceAndFilename(string accessibility, INamedTypeSymbol wrapperSymbol, string theNamespace, - INamedTypeSymbol underlyingSymbol, - VogenKnownSymbols knownSymbols) + INamedTypeSymbol underlyingSymbol) { - string wrapperName = Util.EscapeIfRequired(wrapperSymbol.Name); - var ns = string.IsNullOrEmpty(theNamespace) ? string.Empty : $"namespace {theNamespace};"; string sb = @@ -138,22 +131,18 @@ private static FormatterSourceAndFilename GenerateSourceAndFilename(string acces {{ns}} - {{GenerateSource(accessibility, wrapperSymbol, underlyingSymbol, knownSymbols)}} + {{GenerateSource(accessibility, wrapperSymbol, underlyingSymbol)}} """; - var fn = string.IsNullOrEmpty(theNamespace) ? "" : theNamespace + "."; - string serializerFqn = $"{fn}{wrapperName}MessagePackFormatter"; - var unsanitized = $"{wrapperSymbol.ToDisplayString()}_messagepack.g.cs"; string filename = Util.SanitizeToALegalFilename(unsanitized); - return new FormatterSourceAndFilename(serializerFqn, filename, sb); + return new FormatterSourceAndFilename(filename, sb); } private static string GenerateSource(string accessibility, INamedTypeSymbol wrapperSymbol, - INamedTypeSymbol underlyingSymbol, - VogenKnownSymbols vogenKnownSymbols) + INamedTypeSymbol underlyingSymbol) { var accessor = accessibility; diff --git a/src/Vogen/GenerateCodeForMessagePackMarkers.cs b/src/Vogen/GenerateCodeForMessagePackMarkers.cs index b9116908f3..34120d36f8 100644 --- a/src/Vogen/GenerateCodeForMessagePackMarkers.cs +++ b/src/Vogen/GenerateCodeForMessagePackMarkers.cs @@ -12,7 +12,7 @@ public static void GenerateForMarkerClasses(SourceProductionContext context, { foreach (MarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) { - GenerateCodeForMessagePack.GenerateForAMarkerClass(context, compilation, eachMarkerClass, vogenKnownSymbols); + GenerateCodeForMessagePack.GenerateForAMarkerClass(context, eachMarkerClass); } } } \ No newline at end of file diff --git a/src/Vogen/MarkerAttributeDefinition.cs b/src/Vogen/MarkerAttributeDefinition.cs index e5d8835c46..5bba6813ff 100644 --- a/src/Vogen/MarkerAttributeDefinition.cs +++ b/src/Vogen/MarkerAttributeDefinition.cs @@ -29,7 +29,7 @@ private MarkerAttributeDefinition(ConversionMarker? marker, IEnumerable Diagnostics { get; } - public static MarkerAttributeDefinition Error(ConversionMarkerKind kind, Diagnostic diag) => new(null, [diag]); + public static MarkerAttributeDefinition Error(Diagnostic diag) => new(null, [diag]); public static MarkerAttributeDefinition Ok(ConversionMarkerKind kind, INamedTypeSymbol voSymbol, INamedTypeSymbol underlyingTypeSymbol, INamedTypeSymbol sourceSymbol) => new(marker: new ConversionMarker(kind, voSymbol, underlyingTypeSymbol, sourceSymbol), diagnostics: []); diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs index faef6b8523..a8247a825f 100644 --- a/src/Vogen/ValueObjectGenerator.cs +++ b/src/Vogen/ValueObjectGenerator.cs @@ -128,7 +128,7 @@ private static void Execute( // the user can specify to create the MessagePack generated code as an attribute // or as marker in another project. - GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems, vogenKnownSymbols); + GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems); GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, markerClasses, vogenKnownSymbols); GenerateCodeForBsonSerializers.WriteIfNeeded(spc, compilation, workItems); diff --git a/tests/ConsumerTests/BugFix624.cs b/tests/ConsumerTests/BugFix624.cs index 3458d75c64..021452c0d0 100644 --- a/tests/ConsumerTests/BugFix624.cs +++ b/tests/ConsumerTests/BugFix624.cs @@ -1,8 +1,3 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Metadata; -using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; - namespace ConsumerTests.BugFixTests.BugFix639; [ValueObject(fromPrimitiveCasting: CastOperator.Implicit)] diff --git a/tests/ConsumerTests/BugFixTests/BugFix595.cs b/tests/ConsumerTests/BugFixTests/BugFix595.cs index 1051686bfd..4bb0736483 100644 --- a/tests/ConsumerTests/BugFixTests/BugFix595.cs +++ b/tests/ConsumerTests/BugFixTests/BugFix595.cs @@ -1,6 +1,5 @@ using System.Text.Json; using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Metadata; using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; namespace ConsumerTests.BugFixTests.BugFix595; diff --git a/tests/ConsumerTests/BugFixTests/BugFix624.cs b/tests/ConsumerTests/BugFixTests/BugFix624.cs index 7315af981a..0e1947d26a 100644 --- a/tests/ConsumerTests/BugFixTests/BugFix624.cs +++ b/tests/ConsumerTests/BugFixTests/BugFix624.cs @@ -1,7 +1,4 @@ using System.Text.Json; -using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Metadata; -using SystemTextJsonSerializer = System.Text.Json.JsonSerializer; namespace ConsumerTests.BugFixTests.BugFix624; diff --git a/tests/ConsumerTests/CreationTests.cs b/tests/ConsumerTests/CreationTests.cs index c767dd6114..05f5d48041 100644 --- a/tests/ConsumerTests/CreationTests.cs +++ b/tests/ConsumerTests/CreationTests.cs @@ -1,5 +1,3 @@ -using System.Diagnostics; -using System.Runtime.InteropServices; using @double; using @bool.@byte.@short.@float.@object; using Vogen.Tests.Types; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs index 9df78ea2b8..f62b013bd4 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_Bson.cs @@ -7,7 +7,7 @@ namespace MediumTests.SerializationAndConversionTests; -public partial class ComplexSerializationTests +public partial class ComplexSerializationTests_ServiceStackDotText { [Fact] public void Bson_CanSerializeAndDeserialize() diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_MessagePack.cs similarity index 60% rename from tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs rename to tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_MessagePack.cs index f2ab7ffe6b..990d6fddd1 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_MessagePack.cs @@ -1,7 +1,5 @@ #nullable disable - using MessagePack; -using ServiceStack.Text; using Vogen.IntegrationTests.TestTypes; // ReSharper disable InconsistentNaming @@ -9,217 +7,164 @@ namespace MediumTests.SerializationAndConversionTests; -public partial class ComplexSerializationTests +public partial class ComplexSerializationTests_ServiceStackDotText { - public class ComplexServiceStackDotText + [Fact] + public void MessagePack_CanSerializeAndDeserialize() { - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo.From(true); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo.From(1); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo.From('2'); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo - Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, - TimeSpan.Zero)); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo - Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo - Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo.From(3.33m); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo.From(4.44d); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo.From(5.55f); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo.From(new Bar(42, "Fred")); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtGuidVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo.From(Guid.Empty); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtIntVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo.From(6); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtLongVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo.From(7L); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtStringVo { get; set; } = - Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("8"); - - public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_ServiceStackTextJsonStringVo - { - get; - set; - } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("9"); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo.From(true); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo - { - get; - set; - } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo.From(1); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo.From('2'); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, - TimeSpan.Zero)); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, - DateTimeKind.Utc)); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo.From(3.33m); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo.From(4.44d); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo.From(5.55f); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo.From(new Bar(42, "Fred")); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo - Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtGuidVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo.From(Guid.Empty); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtIntVo - { - get; - set; - } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo.From(6); - - public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtLongVo - { - get; - set; - } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo.From(7L); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo.From(true); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo.From(1); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo.From('2'); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo - Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, - TimeSpan.Zero)); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo - Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo - { - get; - set; - } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo.From(3.33m); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo - Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo.From(4.44d); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo.From(5.55f); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo.From(new Bar(42, "Fred")); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtGuidVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo.From(Guid.Empty); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtIntVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo.From(6); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtLongVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo.From(7L); - - public Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo - Vogen_IntegrationTests_TestTypes_StructVos_SsdtStringVo { get; set; } = - Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo.From("8"); + ConsumerTests.SerializationAndConversionTests.FooFormatter fooFormatter = new(); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo.From(true); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo.From(1); + var customResolver = MessagePack.Resolvers.CompositeResolver.Create( + [ + fooFormatter, + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackTimeOnlyVoMessagePackFormatter(), - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo.From('2'); + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackTimeOnlyVoMessagePackFormatter(), - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, - TimeSpan.Zero)); + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackTimeOnlyVoMessagePackFormatter(), - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, - DateTimeKind.Utc)); + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackBoolVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFloatVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackByteVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackCharVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateOnlyVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDecimalVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDoubleVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFooVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackGuidVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackIntVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackLongVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackShortVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVoMessagePackFormatter(), + new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackTimeOnlyVoMessagePackFormatter() + ], + [MessagePack.Resolvers.StandardResolver.Instance] + ); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo.From(3.33m); + var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo.From(4.44d); + var complex = new ComplexMessagePack(); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo.From(5.55f); + var mp = MessagePackSerializer.Serialize(complex, options); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo.From(new Bar(42, "Fred")); + var deserialized = MessagePackSerializer.Deserialize(mp, options); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtGuidVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo.From(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackStringVo.Value.Should().Be("8"); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtIntVo - { - get; - set; - } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo.From(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackLongVo.Value.Should().Be(7L); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo.From(7L); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackStringVo.Value.Should().Be("8"); - public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo - Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo { get; set; } = - Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo.From("8"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackStringVo.Value.Should().Be("8"); } [MessagePackObject] @@ -495,240 +440,4 @@ public Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVo Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackStringVo { get; set; } = Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVo.From("8"); } - - [Fact] - public void Ssdt_CanSerializeAndDeserialize() - { - var complex = new ComplexServiceStackDotText(); - - string serialized = JsonSerializer.SerializeToString(complex); - ComplexServiceStackDotText deserialized = JsonSerializer.DeserializeFromString(serialized); - - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtLongVo.Value.Should().Be(7L); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtStringVo.Value.Should().Be("8"); - - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtLongVo.Value.Should().Be(7L); - - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtLongVo.Value.Should().Be(7L); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtStringVo.Value.Should().Be("8"); - - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo.Value.Should().Be(7L); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo.Value.Should().Be("8"); - } - - [Fact] - public void MessagePack_CanSerializeAndDeserialize() - { - ConsumerTests.SerializationAndConversionTests.FooFormatter fooFormatter = new(); - - - var customResolver = MessagePack.Resolvers.CompositeResolver.Create( - [ - fooFormatter, - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackBoolVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFloatVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackByteVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackCharVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateOnlyVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDateTimeVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDecimalVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackDoubleVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackFooVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackGuidVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackIntVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackLongVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackShortVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackStringVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.ClassVos.MessagePackTimeOnlyVoMessagePackFormatter(), - - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackBoolVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFloatVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackByteVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackCharVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateOnlyVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDateTimeVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDecimalVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackDoubleVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackFooVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackGuidVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackIntVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackLongVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackShortVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackStringVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordClassVos.MessagePackTimeOnlyVoMessagePackFormatter(), - - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackBoolVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFloatVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackByteVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackCharVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateOnlyVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDateTimeVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDecimalVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackDoubleVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackFooVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackGuidVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackIntVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackLongVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackShortVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackStringVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.StructVos.MessagePackTimeOnlyVoMessagePackFormatter(), - - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackBoolVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFloatVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackByteVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackCharVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateOnlyVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeOffsetVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDateTimeVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDecimalVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackDoubleVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackFooVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackGuidVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackIntVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackLongVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackShortVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackStringVoMessagePackFormatter(), - new Vogen.IntegrationTests.TestTypes.RecordStructVos.MessagePackTimeOnlyVoMessagePackFormatter() - ], - [MessagePack.Resolvers.StandardResolver.Instance] - ); - - var options = MessagePackSerializerOptions.Standard.WithResolver(customResolver); - - var complex = new ComplexMessagePack(); - - var mp = MessagePackSerializer.Serialize(complex, options); - - var deserialized = MessagePackSerializer.Deserialize(mp, options); - - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackLongVo.Value.Should().Be(7L); - deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_MessagePackStringVo.Value.Should().Be("8"); - - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_MessagePackLongVo.Value.Should().Be(7L); - - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackLongVo.Value.Should().Be(7L); - deserialized.Vogen_IntegrationTests_TestTypes_StructVos_MessagePackStringVo.Value.Should().Be("8"); - - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackBoolVo.Value.Should().Be(true); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackByteVo.Value.Should().Be(1); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackCharVo.Value.Should().Be('2'); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeOffsetVo.Value.Should() - .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDateTimeVo.Value.Should() - .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDecimalVo.Value.Should().Be(3.33m); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackDoubleVo.Value.Should().Be(4.44d); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFloatVo.Value.Should().Be(5.55f); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo.Value.Age.Should().Be(42); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackFooVo.Value.Name.Should().Be("Fred"); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackGuidVo.Value.Should().Be(Guid.Empty); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackIntVo.Value.Should().Be(6); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackLongVo.Value.Should().Be(7L); - deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_MessagePackStringVo.Value.Should().Be("8"); - } } \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_ServiceStackDotText.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_ServiceStackDotText.cs new file mode 100644 index 0000000000..dbe444e687 --- /dev/null +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_ServiceStackDotText.cs @@ -0,0 +1,300 @@ +#nullable disable + +using Vogen.IntegrationTests.TestTypes; +// ReSharper disable InconsistentNaming + +// ReSharper disable FunctionComplexityOverflow + +namespace MediumTests.SerializationAndConversionTests; + +public partial class ComplexSerializationTests_ServiceStackDotText +{ + [Fact] + public void Ssdt_CanSerializeAndDeserialize() + { + var complex = new ComplexServiceStackDotText(); + + string serialized = ServiceStack.Text.JsonSerializer.SerializeToString(complex); + ComplexServiceStackDotText deserialized = ServiceStack.Text.JsonSerializer.DeserializeFromString(serialized); + + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_ClassVos_SsdtStringVo.Value.Should().Be("8"); + + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtLongVo.Value.Should().Be(7L); + + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_StructVos_SsdtStringVo.Value.Should().Be("8"); + + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo.Value.Should().Be(true); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo.Value.Should().Be(1); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo.Value.Should().Be('2'); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo.Value.Should() + .Be(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, TimeSpan.Zero)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo.Value.Should() + .Be(new DateTime(2020, 12, 13, 23, 59, 59, 999)); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo.Value.Should().Be(3.33m); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo.Value.Should().Be(4.44d); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo.Value.Should().Be(5.55f); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo.Value.Age.Should().Be(42); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo.Value.Name.Should().Be("Fred"); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtGuidVo.Value.Should().Be(Guid.Empty); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtIntVo.Value.Should().Be(6); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo.Value.Should().Be(7L); + deserialized.Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo.Value.Should().Be("8"); + } + + public class ComplexServiceStackDotText + { + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo + Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_SsdtStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("8"); + + public Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo Vogen_IntegrationTests_TestTypes_ClassVos_ServiceStackTextJsonStringVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.ClassVos.SsdtStringVo.From("9"); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtByteVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo + Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtIntVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_RecordClassVos_SsdtLongVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordClassVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtDecimalVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.StructVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtIntVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo Vogen_IntegrationTests_TestTypes_StructVos_SsdtLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo + Vogen_IntegrationTests_TestTypes_StructVos_SsdtStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.StructVos.SsdtStringVo.From("8"); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtBoolVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtBoolVo.From(true); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtByteVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtByteVo.From(1); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtCharVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtCharVo.From('2'); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeOffsetVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeOffsetVo.From(new DateTimeOffset(2020, 12, 13, 23, 59, 59, 999, + TimeSpan.Zero)); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDateTimeVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDateTimeVo.From(new DateTime(2020, 12, 13, 23, 59, 59, 999, + DateTimeKind.Utc)); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDecimalVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDecimalVo.From(3.33m); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtDoubleVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtDoubleVo.From(4.44d); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFloatVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFloatVo.From(5.55f); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtFooVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtFooVo.From(new Bar(42, "Fred")); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtGuidVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtGuidVo.From(Guid.Empty); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtIntVo + { + get; + set; + } = Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtIntVo.From(6); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtLongVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtLongVo.From(7L); + + public Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo + Vogen_IntegrationTests_TestTypes_RecordStructVos_SsdtStringVo { get; set; } = + Vogen.IntegrationTests.TestTypes.RecordStructVos.SsdtStringVo.From("8"); + } +} \ No newline at end of file diff --git a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs index a5099b2fa2..286154f845 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/ComplexSerializationTests_SytemTextJson.cs @@ -6,7 +6,7 @@ namespace MediumTests.SerializationAndConversionTests; -public partial class ComplexSerializationTests +public partial class ComplexSerializationTests_ServiceStackDotText { public class ComplexSystemTextJson { diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs index 1ae798efb3..d70854f402 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/MessagePackSerializationTests.cs @@ -1,4 +1,3 @@ -using ConsumerTests.BugFixTests; using MessagePack; using MessagePack.Formatters; using Vogen.IntegrationTests.TestTypes; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/StringVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/StringVoTests.cs index 6f86cc9450..83bb51800d 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/StringVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordClassVos/StringVoTests.cs @@ -12,6 +12,7 @@ using LinqToDB.Data; using LinqToDB.DataProvider.SQLite; using LinqToDB.Mapping; +// ReSharper disable AssignNullToNotNullAttribute namespace Vogen.IntegrationTests.SerializationAndConversionTests.RecordClassVos; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs index 095fa36f9c..8fdb319313 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/MessagePackSerializationTests.cs @@ -1,4 +1,3 @@ -using ConsumerTests.BugFixTests; using MessagePack; using MessagePack.Formatters; using Vogen.IntegrationTests.TestTypes; diff --git a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/StringVoTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/StringVoTests.cs index 1b4c9982ed..cf4ff21707 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/StringVoTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/RecordStructVos/StringVoTests.cs @@ -12,6 +12,9 @@ using LinqToDB.Data; using LinqToDB.DataProvider.SQLite; using LinqToDB.Mapping; +// ReSharper disable AssignNullToNotNullAttribute +// ReSharper disable EqualExpressionComparison +// ReSharper disable RedundantCast namespace Vogen.IntegrationTests.SerializationAndConversionTests.RecordStructVos; @@ -40,10 +43,8 @@ public void equality_between_same_value_objects() } [Fact] - public void equality_between_different_value_objects() - { + public void equality_between_different_value_objects() => StringVo.From("hello!").Equals(AnotherStringVo.From("hello!")).Should().BeFalse(); - } [Fact] public void CanSerializeToString_WithNewtonsoftJsonProvider() diff --git a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs index b4d87dbe5e..9264c831fc 100644 --- a/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs +++ b/tests/ConsumerTests/SerializationAndConversionTests/StructVos/MessagePackSerializationTests.cs @@ -1,4 +1,3 @@ -using ConsumerTests.BugFixTests; using MessagePack; using MessagePack.Formatters; using Vogen.IntegrationTests.TestTypes; diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt index 55831887d8..7f93eb95e3 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_and_efcore_markers.verified.txt @@ -140,6 +140,11 @@ public static class MyId__Ext namespace @double; public partial class MyMarkers { + public static global::MessagePack.Formatters.IMessagePackFormatter[] MessagePackFormatters => new global::MessagePack.Formatters.IMessagePackFormatter[] + { + new MyIdMessagePackFormatter() + }; + public partial class MyIdMessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<@double.MyId> { public void Serialize(ref global::MessagePack.MessagePackWriter writer, @double.MyId value, global::MessagePack.MessagePackSerializerOptions options) => writer.Write(value.Value); diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt index 7a22ec065f..cd6acd9e61 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/GeneralTests.Generates_messagepack_markers.verified.txt @@ -21,6 +21,11 @@ namespace @double; public partial class MyMarkers { + public static global::MessagePack.Formatters.IMessagePackFormatter[] MessagePackFormatters => new global::MessagePack.Formatters.IMessagePackFormatter[] + { + new MyIdMessagePackFormatter() + }; + public partial class MyIdMessagePackFormatter : global::MessagePack.Formatters.IMessagePackFormatter<@double.MyId> { public void Serialize(ref global::MessagePack.MessagePackWriter writer, @double.MyId value, global::MessagePack.MessagePackSerializerOptions options) => writer.Write(value.Value); From f3c7ae8b08df3aa9e92d48069fa8157706bdc434 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Wed, 13 Nov 2024 12:46:11 +0000 Subject: [PATCH 09/10] Post implementation tidy up --- src/Vogen/ConversionMarkerKind.cs | 8 +++ src/Vogen/ConversionMarkers.cs | 46 +++++++++-------- src/Vogen/Diagnostics/RuleIdentifiers.cs | 1 - src/Vogen/GenerateCodeForEfCoreMarkers.cs | 7 +-- src/Vogen/GenerateCodeForMessagePack.cs | 49 ++++++++++++++----- .../GenerateCodeForMessagePackMarkers.cs | 18 ------- src/Vogen/GenerateCodeForToString.cs | 8 ++- .../Conversions/IGenerateConversion.cs | 1 + src/Vogen/MarkerAttribute2.cs | 49 ------------------- src/Vogen/UserProvidedToStringMethods.cs | 3 +- src/Vogen/ValueObjectGenerator.cs | 8 +-- 11 files changed, 82 insertions(+), 116 deletions(-) create mode 100644 src/Vogen/ConversionMarkerKind.cs delete mode 100644 src/Vogen/GenerateCodeForMessagePackMarkers.cs delete mode 100644 src/Vogen/MarkerAttribute2.cs diff --git a/src/Vogen/ConversionMarkerKind.cs b/src/Vogen/ConversionMarkerKind.cs new file mode 100644 index 0000000000..6c799d5491 --- /dev/null +++ b/src/Vogen/ConversionMarkerKind.cs @@ -0,0 +1,8 @@ +namespace Vogen; + +public enum ConversionMarkerKind +{ + Unrecognized, + EFCore, + MessagePack, +} \ No newline at end of file diff --git a/src/Vogen/ConversionMarkers.cs b/src/Vogen/ConversionMarkers.cs index 0e95005b9f..7c64a596ef 100644 --- a/src/Vogen/ConversionMarkers.cs +++ b/src/Vogen/ConversionMarkers.cs @@ -29,10 +29,8 @@ public static IEnumerable TryGetMarkerAttributes(INamedTypeSymbol a => _knownMarkerAttributes.ContainsKey(a.AttributeClass?.MetadataName ?? "")); } - public static MarkerClassDefinition? GetConversionMarkerClassDefinitionFromAttribute(GeneratorSyntaxContext context) + public static MarkerClassDefinition? GetConversionMarkerClassesFromAttribute(GeneratorSyntaxContext context) { - // var voSyntaxInformation = (TypeDeclarationSyntax) context.Node; - var semanticModel = context.SemanticModel; ISymbol declaredSymbol = semanticModel.GetDeclaredSymbol(context.Node)!; @@ -50,9 +48,8 @@ public static IEnumerable TryGetMarkerAttributes(INamedTypeSymbol public static bool IsTarget(SyntaxNode node) => node is TypeDeclarationSyntax { AttributeLists.Count: > 0 }; - - - public static MarkerAttributeDefinition? TryBuild(AttributeData markerAtt, in INamedTypeSymbol? markerClassSymbol) + + private static MarkerAttributeDefinition? TryBuild(AttributeData markerAtt, in INamedTypeSymbol? markerClassSymbol) { ImmutableArray args = markerAtt.ConstructorArguments; @@ -64,54 +61,61 @@ public static bool IsTarget(SyntaxNode node) => return null; } - if (markerAtt.AttributeClass == null) + if (markerAtt.AttributeClass?.TypeArguments.SingleOrDefaultIfMultiple() is not INamedTypeSymbol voSymbol) { return null; } - var voSymbol = markerAtt.AttributeClass.TypeArguments.SingleOrDefaultIfMultiple() as INamedTypeSymbol; + ConversionMarkerKind markerKind = ResolveMarkerKind(markerAtt); - if (voSymbol is null) + if(markerKind is ConversionMarkerKind.Unrecognized) { return null; } - ConversionMarkerKind markerKind = ResolveMarkerKind(markerAtt); - - if(markerKind is ConversionMarkerKind.Unrecognized) return null; - if (!VoFilter.IsTarget(voSymbol)) { -// return ConversionMarkerAttributeDefinition.Error(markerKind, DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol)); - return MarkerAttributeDefinition.Error(DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol)); + return MarkerAttributeDefinition.Error( + DiagnosticsCatalogue.TypesReferencedInAConversionMarkerMustBeaValueObjects(markerClassSymbol!, voSymbol)); } List voAttributes = VoFilter.TryGetValueObjectAttributes(voSymbol).ToList(); - if(voAttributes.Count != 1) return null; + if(voAttributes.Count != 1) + { + return null; + } AttributeData voAttribute = voAttributes[0]; VogenConfigurationBuildResult config = BuildConfigurationFromAttributes.TryBuildFromValueObjectAttribute(voAttribute); - if(config.HasDiagnostics) return null; + if(config.HasDiagnostics) + { + return null; + } VogenConfiguration c = config.ResultingConfiguration!; - var underlyingType = c.UnderlyingType ?? ResolveUnderlyingType(voSymbol); + var underlyingType = c.UnderlyingType ?? TryResolveUnderlyingType(voSymbol); if (underlyingType is null) { - return MarkerAttributeDefinition.Error(DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive(markerClassSymbol!, voSymbol, markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation())); + return MarkerAttributeDefinition.Error( + DiagnosticsCatalogue.VoReferencedInAConversionMarkerMustExplicitlySpecifyPrimitive( + markerClassSymbol!, + voSymbol, + markerAtt.ApplicationSyntaxReference?.GetSyntax().GetLocation())); } return MarkerAttributeDefinition.Ok(markerKind, voSymbol, underlyingType, markerClassSymbol!); } private static ConversionMarkerKind ResolveMarkerKind(AttributeData att) => + // ReSharper disable once CanSimplifyDictionaryTryGetValueWithGetValueOrDefault _knownMarkerAttributes.TryGetValue(att.AttributeClass?.MetadataName ?? "", out var kind) ? kind : ConversionMarkerKind.Unrecognized; - private static INamedTypeSymbol? ResolveUnderlyingType(INamedTypeSymbol method) + private static INamedTypeSymbol? TryResolveUnderlyingType(INamedTypeSymbol method) { ImmutableArray ms = method.GetMembers("Value"); @@ -122,6 +126,6 @@ private static ConversionMarkerKind ResolveMarkerKind(AttributeData att) => IPropertySymbol? prop = ms[0] as IPropertySymbol; - return (INamedTypeSymbol)prop!.Type; + return prop!.Type as INamedTypeSymbol; } } \ No newline at end of file diff --git a/src/Vogen/Diagnostics/RuleIdentifiers.cs b/src/Vogen/Diagnostics/RuleIdentifiers.cs index 709e8f02e0..652f65791c 100644 --- a/src/Vogen/Diagnostics/RuleIdentifiers.cs +++ b/src/Vogen/Diagnostics/RuleIdentifiers.cs @@ -37,7 +37,6 @@ public static class RuleIdentifiers public const string IncorrectUseOfInstanceField = "VOG027"; public const string IncorrectUseOfNormalizeInputMethod = "VOG028"; public const string ExplicitlySpecifyTypeInValueObjectAttribute = "VOG029"; - //public const string EfCoreTargetMustExplicitlySpecifyItsPrimitive = "VOG030"; public const string TypesReferencedInAConversionMarkerMustBeaValueObjects = "VOG031"; public const string DoNotThrowFromUserCode = "VOG032"; public const string UseReadonlyStructInsteadOfStruct = "VOG033"; diff --git a/src/Vogen/GenerateCodeForEfCoreMarkers.cs b/src/Vogen/GenerateCodeForEfCoreMarkers.cs index 3103e7164a..27e6e6103f 100644 --- a/src/Vogen/GenerateCodeForEfCoreMarkers.cs +++ b/src/Vogen/GenerateCodeForEfCoreMarkers.cs @@ -73,7 +73,7 @@ private static void WriteEachIfNeeded(SourceProductionContext context, Conversio SourceText sourceText = SourceText.From(sb, Encoding.UTF8); - string filename = Util.GetLegalMarkerClassFilename(markerClass.MarkerClassSymbol, markerClass.VoSymbol, markerClass.Kind); + string filename = Util.GetLegalFilenameForMarkerClass(markerClass.MarkerClassSymbol, markerClass.VoSymbol, markerClass.Kind); Util.TryWriteUsingUniqueFilename(filename, context, sourceText); } @@ -120,9 +120,7 @@ private static void StoreExtensionMethodToRegisterAllInMarkerClass( SourceText sourceText = SourceText.From(source, Encoding.UTF8); - var filename = Util.GetLegalMarkerClassFilename(markerSymbol, ConversionMarkerKind.EFCore); - - //string filename = Util.SanitizeToALegalFilename($"{markerSymbol.ToDisplayString()}.g.cs"); + var filename = Util.GetLegalFilenameForMarkerClass(markerSymbol, ConversionMarkerKind.EFCore); Util.TryWriteUsingUniqueFilename(filename, context, sourceText); @@ -146,5 +144,4 @@ string GenerateBody() return sb.ToString(); } } - } \ No newline at end of file diff --git a/src/Vogen/GenerateCodeForMessagePack.cs b/src/Vogen/GenerateCodeForMessagePack.cs index f8bc7efd72..df2b459136 100644 --- a/src/Vogen/GenerateCodeForMessagePack.cs +++ b/src/Vogen/GenerateCodeForMessagePack.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -9,7 +10,15 @@ namespace Vogen; internal class GenerateCodeForMessagePack { - public static void GenerateForAMarkerClass(SourceProductionContext context, MarkerClassDefinition markerClass) + public static void GenerateForMarkerClasses(SourceProductionContext context, ImmutableArray conversionMarkerClasses) + { + foreach (MarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) + { + GenerateCodeForMessagePack.GenerateForAMarkerClass(context, eachMarkerClass); + } + } + + private static void GenerateForAMarkerClass(SourceProductionContext context, MarkerClassDefinition markerClass) { var markerClassSymbol = markerClass.MarkerClassSymbol; @@ -41,7 +50,7 @@ public static void GenerateForAMarkerClass(SourceProductionContext context, Mark SourceText sourceText = Util.FormatSource(s); - string filename = Util.GetLegalMarkerClassFilename(markerClass.MarkerClassSymbol, ConversionMarkerKind.MessagePack); + string filename = Util.GetLegalFilenameForMarkerClass(markerClass.MarkerClassSymbol, ConversionMarkerKind.MessagePack); Util.TryWriteUsingUniqueFilename(filename, context, sourceText); @@ -63,9 +72,11 @@ string GenerateEach() m => m.Marker?.Kind is ConversionMarkerKind.MessagePack).Select( x => { - //if (x is null) return null; - if (x.Marker is null) return null; - + if (x.Marker is null) + { + return null; + } + string wrapperNameShort = x.Marker.VoSymbol.Name; return $"new {wrapperNameShort}MessagePackFormatter()"; @@ -139,7 +150,6 @@ private static FormatterSourceAndFilename GenerateSourceAndFilename(string acces return new FormatterSourceAndFilename(filename, sb); } - private static string GenerateSource(string accessibility, INamedTypeSymbol wrapperSymbol, INamedTypeSymbol underlyingSymbol) @@ -151,11 +161,6 @@ private static string GenerateSource(string accessibility, string underlyingTypeName = underlyingSymbol.FullName() ?? underlyingSymbol.Name; - // if (readAndWriteMethods.Item1.Length == 0) - // { - // return $"#error unsupported underlying type '{underlyingSymbol.FullName()}' for value object '{wrapperSymbol.Name}' - you need to turn off MessagePack support for this value object and provide your own resolver"; - // } - string nativeReadMethod = TryGetNativeReadMethod(underlyingSymbol); if (!string.IsNullOrEmpty(nativeReadMethod)) @@ -224,4 +229,26 @@ private static string TryGetNativeReadMethod(INamedTypeSymbol primitive) => SpecialType.System_UInt64 => "ReadUInt64()", _ => "" }; + + /// + /// Represents a marker for a MessagePack conversion + /// + /// The namespace of the containing marker class. + /// The symbol for the value object wrapper class. + /// The symbol for the underlying primitive type. + /// The accessibility (public, internal, etc.) of the generated type. + private record MessagePackStandalone( + string ContainerNamespace, + INamedTypeSymbol WrapperType, + INamedTypeSymbol UnderlyingType, + string WrapperAccessibility) + { + public static MessagePackStandalone FromWorkItem(VoWorkItem voWorkItem) + { + var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); + var accessor = isPublic ? "public" : "internal"; + + return new(voWorkItem.FullNamespace, voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); + } + } } \ No newline at end of file diff --git a/src/Vogen/GenerateCodeForMessagePackMarkers.cs b/src/Vogen/GenerateCodeForMessagePackMarkers.cs deleted file mode 100644 index 34120d36f8..0000000000 --- a/src/Vogen/GenerateCodeForMessagePackMarkers.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; - -namespace Vogen; - -internal class GenerateCodeForMessagePackMarkers -{ - public static void GenerateForMarkerClasses(SourceProductionContext context, - Compilation compilation, - ImmutableArray conversionMarkerClasses, - VogenKnownSymbols vogenKnownSymbols) - { - foreach (MarkerClassDefinition? eachMarkerClass in conversionMarkerClasses) - { - GenerateCodeForMessagePack.GenerateForAMarkerClass(context, eachMarkerClass); - } - } -} \ No newline at end of file diff --git a/src/Vogen/GenerateCodeForToString.cs b/src/Vogen/GenerateCodeForToString.cs index 3abf54589e..7cf30afc45 100644 --- a/src/Vogen/GenerateCodeForToString.cs +++ b/src/Vogen/GenerateCodeForToString.cs @@ -25,8 +25,7 @@ private static string GenerateAnyHoistedToStringMethods(GenerationParameters gen { List methodsToWrite = FilterOutUserSuppliedMethods( item.ToStringInformation.ToStringMethodsOnThePrimitive, - item.UserProvidedOverloads.ToStringOverloads, - item).ToList(); + item.UserProvidedOverloads.ToStringOverloads).ToList(); StringBuilder sb = new StringBuilder(); @@ -66,12 +65,11 @@ private static string GenerateAnyHoistedToStringMethods(GenerationParameters gen // or the wrapper. static IEnumerable FilterOutUserSuppliedMethods( List methodsOnThePrimitive, - UserProvidedToStringMethods methodsOnTheWrapper, - VoWorkItem vo) + UserProvidedToStringMethods methodsOnTheWrapper) { foreach (var eachMethod in methodsOnThePrimitive) { - if (!methodsOnTheWrapper.Contains(eachMethod, vo)) + if (!methodsOnTheWrapper.Contains(eachMethod)) { yield return eachMethod; } diff --git a/src/Vogen/Generators/Conversions/IGenerateConversion.cs b/src/Vogen/Generators/Conversions/IGenerateConversion.cs index fec6a58dc5..d0551564ab 100644 --- a/src/Vogen/Generators/Conversions/IGenerateConversion.cs +++ b/src/Vogen/Generators/Conversions/IGenerateConversion.cs @@ -1,4 +1,5 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; +// ReSharper disable UnusedParameter.Global namespace Vogen.Generators.Conversions; diff --git a/src/Vogen/MarkerAttribute2.cs b/src/Vogen/MarkerAttribute2.cs deleted file mode 100644 index 50dfa9aec6..0000000000 --- a/src/Vogen/MarkerAttribute2.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace Vogen; - -/// -/// Represents a marker for a MessagePack conversion -/// -/// The namespace of the containing marker class. -/// The type name of the containing marker class. -/// The symbol for the value object wrapper class. -/// The symbol for the underlying primitive type. -/// The accessibility (public, internal, etc.) of the generated type. -public record MarkerAttribute2( - string ContainerNamespace, - string ContainerTypeName, - INamedTypeSymbol WrapperType, - INamedTypeSymbol UnderlyingType, - string WrapperAccessibility) -{ - public static MarkerAttribute2 FromWorkItem(VoWorkItem voWorkItem) - { - var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); - var accessor = isPublic ? "public" : "internal"; - - return new(voWorkItem.FullNamespace, "", voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); - } -} - -/// -/// Represents a marker for a MessagePack conversion -/// -/// The namespace of the containing marker class. -/// The symbol for the value object wrapper class. -/// The symbol for the underlying primitive type. -/// The accessibility (public, internal, etc.) of the generated type. -public record MessagePackStandalone( - string ContainerNamespace, - INamedTypeSymbol WrapperType, - INamedTypeSymbol UnderlyingType, - string WrapperAccessibility) -{ - public static MessagePackStandalone FromWorkItem(VoWorkItem voWorkItem) - { - var isPublic = voWorkItem.WrapperType.DeclaredAccessibility.HasFlag(Accessibility.Public); - var accessor = isPublic ? "public" : "internal"; - - return new(voWorkItem.FullNamespace, voWorkItem.WrapperType, voWorkItem.UnderlyingType, accessor); - } -} \ No newline at end of file diff --git a/src/Vogen/UserProvidedToStringMethods.cs b/src/Vogen/UserProvidedToStringMethods.cs index ca78914ded..efb9e24027 100644 --- a/src/Vogen/UserProvidedToStringMethods.cs +++ b/src/Vogen/UserProvidedToStringMethods.cs @@ -18,9 +18,8 @@ public class UserProvidedToStringMethods : IEnumerable /// Sees if the items held contains the method from the primitive. /// /// - /// /// - public bool Contains(IMethodSymbol methodFromPrimitive, VoWorkItem vo) + public bool Contains(IMethodSymbol methodFromPrimitive) { foreach (var eachUserMethod in _userMethods) { diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs index a8247a825f..547dbd586e 100644 --- a/src/Vogen/ValueObjectGenerator.cs +++ b/src/Vogen/ValueObjectGenerator.cs @@ -27,9 +27,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context) var targetsAndConfig = collectedVos.Combine(found.GlobalConfig.Collect()); - var targetsConfigAndConversionMarkers = targetsAndConfig.Combine(found.ConverterMarkerClasses.Collect()); + var targetsConfigAndMarkers = targetsAndConfig.Combine(found.ConverterMarkerClasses.Collect()); - var compilationAndValues = context.CompilationProvider.Combine(targetsConfigAndConversionMarkers); + var compilationAndValues = context.CompilationProvider.Combine(targetsConfigAndMarkers); var everything = compilationAndValues.Combine(knownSymbols); @@ -71,7 +71,7 @@ private static Found GetTargets(SyntaxValueProvider syntaxProvider) IncrementalValuesProvider converterMarkerClasses = syntaxProvider.CreateSyntaxProvider( predicate: (node, _) => ConversionMarkers.IsTarget(node), - transform: (ctx, _) => ConversionMarkers.GetConversionMarkerClassDefinitionFromAttribute(ctx)) + transform: (ctx, _) => ConversionMarkers.GetConversionMarkerClassesFromAttribute(ctx)) .Where(static m => m is not null)!; return new Found(targets, globalConfig, converterMarkerClasses); @@ -129,7 +129,7 @@ private static void Execute( // the user can specify to create the MessagePack generated code as an attribute // or as marker in another project. GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems); - GenerateCodeForMessagePackMarkers.GenerateForMarkerClasses(spc, compilation, markerClasses, vogenKnownSymbols); + GenerateCodeForMessagePack.GenerateForMarkerClasses(spc, markerClasses); GenerateCodeForBsonSerializers.WriteIfNeeded(spc, compilation, workItems); From 95b2d38521e93fbed7894c7ed31587553bb8272d Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Wed, 13 Nov 2024 16:40:28 +0000 Subject: [PATCH 10/10] Tidy up --- src/Vogen/MarkerAttributeDefinition.cs | 7 ------- src/Vogen/Util.cs | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Vogen/MarkerAttributeDefinition.cs b/src/Vogen/MarkerAttributeDefinition.cs index 5bba6813ff..25464c6c9a 100644 --- a/src/Vogen/MarkerAttributeDefinition.cs +++ b/src/Vogen/MarkerAttributeDefinition.cs @@ -4,13 +4,6 @@ namespace Vogen; -public enum ConversionMarkerKind -{ - Unrecognized, - EFCore, - MessagePack, -} - /// /// Represents the *definition* of a 'marker attribute, e.g. an 'EFCore marker' or 'message pack marker' - that is, a partial class decorated with an /// attribute such as `EfCoreConverter`, or 'MemoryPackConverter'. This is the singular item; a particular attribute on the method, diff --git a/src/Vogen/Util.cs b/src/Vogen/Util.cs index ee429eafac..1186a5730c 100644 --- a/src/Vogen/Util.cs +++ b/src/Vogen/Util.cs @@ -437,7 +437,7 @@ static string GetMessageToReport(VoWorkItem item) => public static string GetModifiersForValueAndIsInitializedFields(VoWorkItem workItem) => workItem.Config.Conversions.HasFlag(Vogen.Conversions.XmlSerializable) ? "" : "readonly"; - internal static string GetLegalMarkerClassFilename(INamedTypeSymbol markerClassSymbol, ConversionMarkerKind conversionKind) + internal static string GetLegalFilenameForMarkerClass(INamedTypeSymbol markerClassSymbol, ConversionMarkerKind conversionKind) { var unsanitized = $"{markerClassSymbol.ToDisplayString()}.{conversionKind}.g.cs"; string filename = Util.SanitizeToALegalFilename(unsanitized); @@ -445,7 +445,7 @@ internal static string GetLegalMarkerClassFilename(INamedTypeSymbol markerClassS return filename; } - internal static string GetLegalMarkerClassFilename(INamedTypeSymbol markerClassSymbol, INamedTypeSymbol voSymbol, ConversionMarkerKind conversionKind) + internal static string GetLegalFilenameForMarkerClass(INamedTypeSymbol markerClassSymbol, INamedTypeSymbol voSymbol, ConversionMarkerKind conversionKind) { var unsanitized = $"{markerClassSymbol.ToDisplayString()}.{voSymbol.ToDisplayString()}.{conversionKind}.g.cs"; string filename = Util.SanitizeToALegalFilename(unsanitized);