diff --git a/samples/Vogen.Examples/TypicalScenarios/NullableExamples.cs b/samples/Vogen.Examples/TypicalScenarios/NullableExamples.cs index 449900d009..07c2417677 100644 --- a/samples/Vogen.Examples/TypicalScenarios/NullableExamples.cs +++ b/samples/Vogen.Examples/TypicalScenarios/NullableExamples.cs @@ -9,7 +9,6 @@ // ReSharper disable ClassNeverInstantiated.Global - // ReSharper disable RedundantNullableDirective using System; @@ -32,11 +31,6 @@ public Task Run() void NullableDisabledClassValueObjectWrappingAnInt() { - // Error CS1503 : Argument 1: cannot convert from '' to 'int' - // Even though nullability was disabled, because it wraps an int, we can pass null. - // _ = NullableDisabledClassWrappingInt.From(null); - _ = NullableDisabledClassWrappingInt.TryFrom(null); - var nd1 = NullableDisabledClassWrappingInt.From(1); var nd2 = NullableDisabledClassWrappingInt.From(2); @@ -47,7 +41,7 @@ void NullableDisabledClassValueObjectWrappingAnInt() // Even though we turned off nullability for this value object, the signatures for some methods // are 'hoisted' from the primitive. // _ = NullableDisabledClassWrappingInt.TryParse((string)null, out _); - + _ = nd1.CompareTo(null); _ = nd1.Equals(null as object); @@ -60,11 +54,6 @@ void NullableDisabledClassValueObjectWrappingAnInt() void NullableEnabledClassValueObjectWrappingAnInt() { - // Error CS1503 : Argument 1: cannot convert from '' to 'int' - // Even though nullability was disabled, because it wraps an int, we can pass null. - // NullableEnabledClassWrappingInt.From(null); - // NullableEnabledClassWrappingInt.TryFrom(null); - var nd1 = NullableEnabledClassWrappingInt.From(1); var nd2 = NullableEnabledClassWrappingInt.From(2); @@ -76,7 +65,7 @@ void NullableEnabledClassValueObjectWrappingAnInt() // Even though we turned off nullability for this value object, the signatures for some methods // are 'hoisted' from the primitive. // _ = NullableEnabledClassWrappingInt.TryParse((string)null, out _); - + _ = nd1.CompareTo(null); _ = nd1.Equals(null); @@ -88,11 +77,6 @@ void NullableEnabledClassValueObjectWrappingAnInt() void NullableDisabledStructValueObjectWrappingAnInt() { - // Error CS1503 : Argument 1: cannot convert from '' to 'int' - // Even though nullability was disabled, because it wraps an int, we can pass null. - // _ = NullableDisabledStructWrappingInt.From(null); - // NullableDisabledStructWrappingInt.TryFrom(null); - var nd1 = NullableDisabledStructWrappingInt.From(1); var nd2 = NullableDisabledStructWrappingInt.From(2); @@ -103,26 +87,20 @@ void NullableDisabledStructValueObjectWrappingAnInt() // Even though we turned off nullability for this value object, the signatures for some methods // are 'hoisted' from the primitive. // _ = NullableDisabledStructWrappingInt.TryParse((string)null, out _); - + _ = nd1.CompareTo(null); _ = nd1.Equals(null); _ = nd1 == nd2; _ = nd1 == 1; - + // makes no sense to compare to null as it's a struct, resulting in Error CS8073 : The result of the expression is always 'false' // _ = nd1 == null; } void NullableEnabledStructValueObjectWrappingAnInt() { - // Error CS1503 : Argument 1: cannot convert from '' to 'int' - // Even though nullability was enabled, because the value object itself - // is a class, we still get CS1503 - // NullableEnabledStructWrappingInt.From(null); - // NullableEnabledStructWrappingInt.TryFrom(null); - var nd1 = NullableEnabledStructWrappingInt.From(1); var nd2 = NullableEnabledStructWrappingInt.From(2); @@ -134,7 +112,7 @@ void NullableEnabledStructValueObjectWrappingAnInt() // Even though we turned off nullability for this value object, the signatures for some methods // are 'hoisted' from the primitive. // _ = NullableEnabledStructWrappingInt.TryParse((string)null, out _); - + _ = nd1.CompareTo(null); _ = nd1.Equals(null); @@ -149,12 +127,12 @@ void NullableDisabledClassValueObjectWrappingAString() { // No issues - we've disabled null when creating this value object, so no warnings NullableDisabledClassWrappingString c1 = NullableDisabledClassWrappingString.From(null); - + // CS8600 - even though nullability is disabled, the `MaybeNullWhen` creates the error. // _ = NullableDisabledClassWrappingString.TryFrom(null, out NullableDisabledClassWrappingString c2); - + Console.WriteLine(c1.Value); // NullReferenceException - + var nd1 = NullableDisabledClassWrappingString.From("1"); var nd2 = NullableDisabledClassWrappingString.From("2"); @@ -167,7 +145,7 @@ void NullableDisabledClassValueObjectWrappingAString() // Even though we turned off nullability for this value object, the signatures for some methods // are 'hoisted' from the primitive. // _ = NullableDisabledClassWrappingString.TryParse((string)null, out _); - + _ = nd1.CompareTo(null); // not marked as nullable @@ -187,13 +165,13 @@ void NullableEnabledClassValueObjectWrappingAString() { // CS8625 - cannot provide null as nullability is enabled in the generated value object // NullableEnabledClassWrappingString c1 = NullableEnabledClassWrappingString.From(null); - + // CS8600 - needs nullable // _ = NullableEnabledClassWrappingString.TryFrom(null, out NullableEnabledClassWrappingString c2); - + // OK _ = NullableEnabledClassWrappingString.TryFrom(null, out NullableEnabledClassWrappingString? _); - + var vo1 = NullableEnabledClassWrappingString.From("1"); var vo2 = NullableEnabledClassWrappingString.From("2"); @@ -202,17 +180,17 @@ void NullableEnabledClassValueObjectWrappingAString() // OK _ = NullableEnabledClassWrappingString.TryParse(null, CultureInfo.InvariantCulture, out _); - + // CS8602 dereference of possibly null reference // Console.WriteLine(r.Value); - + _ = vo1.CompareTo(null); // not marked as nullable _ = vo1.Equals(null as string); // CS8600 - as not marked as nullable - + //OK _ = vo1.Equals(null as string); _ = vo1.Equals(null as NullableEnabledClassWrappingString); @@ -229,13 +207,13 @@ void NullableEnabledStructValueObjectWrappingString() { // CS8625 - cannot provide null as nullability is enabled in the generated value object // NullableEnabledStructWrappingString c1 = NullableEnabledStructWrappingString.From(null); - + // CS8600 - needs nullable // _ = NullableEnabledStructWrappingString.TryFrom(null, out NullableEnabledStructWrappingString c2); - + // OK - nullable not needed because the value object is a value type _ = NullableEnabledStructWrappingString.TryFrom(null, out NullableEnabledStructWrappingString _); - + var vo1 = NullableEnabledStructWrappingString.From("1"); var vo2 = NullableEnabledStructWrappingString.From("2"); @@ -244,7 +222,7 @@ void NullableEnabledStructValueObjectWrappingString() // OK _ = NullableEnabledStructWrappingString.TryParse(null, CultureInfo.InvariantCulture, out _); - + _ = vo1.CompareTo(null); // marked as nullable @@ -264,10 +242,10 @@ void NullableDisabledStructValueObjectWrappingString() { // OK - even though nullability is disabled, the _ = NullableDisabledStructWrappingString.From(null); - + // OK _ = NullableDisabledStructWrappingString.TryFrom(null, out NullableDisabledStructWrappingString _); - + var vo1 = NullableDisabledStructWrappingString.From("1"); var vo2 = NullableDisabledStructWrappingString.From("2"); @@ -276,17 +254,17 @@ void NullableDisabledStructValueObjectWrappingString() // OK _ = NullableDisabledStructWrappingString.TryParse(null, CultureInfo.InvariantCulture, out _); - + // CS8602 dereference of possibly null reference // Console.WriteLine(r.Value); - + _ = vo1.CompareTo(null); // not marked as nullable _ = vo1.Equals(null); // CS8600 - as not marked as nullable - + //OK _ = vo1.Equals(null); _ = vo1.Equals(null as object); @@ -301,32 +279,37 @@ void NullableDisabledStructValueObjectWrappingString() } #nullable disable -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] public partial class NullableDisabledClassWrappingInt; -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] public partial struct NullableDisabledStructWrappingInt; -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, + parsableForStrings: GenerateMethodsAndInterface)] public partial class NullableDisabledClassWrappingString; -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, + parsableForStrings: GenerateMethodsAndInterface)] public partial struct NullableDisabledStructWrappingString; #nullable restore + #nullable enable -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] public partial class NullableEnabledClassWrappingInt; -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces)] public partial struct NullableEnabledStructWrappingInt; -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, + parsableForStrings: GenerateMethodsAndInterface)] public partial class NullableEnabledClassWrappingString; -[ValueObject(comparison:UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, parsableForStrings: GenerateMethodsAndInterface)] +[ValueObject(comparison: UseUnderlying, parsableForPrimitives: HoistMethodsAndInterfaces, + parsableForStrings: GenerateMethodsAndInterface)] public partial struct NullableEnabledStructWrappingString; #nullable restore \ No newline at end of file diff --git a/samples/Vogen.Examples/Vogen.Examples.csproj b/samples/Vogen.Examples/Vogen.Examples.csproj index 9dd4b8e739..872a96c41c 100644 --- a/samples/Vogen.Examples/Vogen.Examples.csproj +++ b/samples/Vogen.Examples/Vogen.Examples.csproj @@ -51,7 +51,6 @@ - NULLABLE_ENABLED_BUILD enable diff --git a/src/Vogen/GenerateCodeForTryParse.cs b/src/Vogen/GenerateCodeForTryParse.cs index efbc6aa69f..9d4fd5dde2 100644 --- a/src/Vogen/GenerateCodeForTryParse.cs +++ b/src/Vogen/GenerateCodeForTryParse.cs @@ -152,13 +152,14 @@ private static void BuildHoistedTryParseMethod(IMethodSymbol methodSymbol, Strin private static string GenerateCallToValidationIfNeeded(VoWorkItem workItem, string parameterName) { + string bangForWrapper = workItem.Nullable.BangForWrapper; if (workItem.ValidateMethod is not null) { return $$""" var validation = {{workItem.TypeToAugment.Identifier}}.{{workItem.ValidateMethod.Identifier.Value}}({{parameterName}}); if (validation != Vogen.Validation.Ok) { - result = default; + result = default{{bangForWrapper}}; return false; } diff --git a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs index b0f218096e..96b4d5f097 100644 --- a/tests/SnapshotTests/GeneralStuff/GeneralTests.cs +++ b/tests/SnapshotTests/GeneralStuff/GeneralTests.cs @@ -44,18 +44,13 @@ public async Task Nullable_enabled_if_set_in_scope(string type) { var source = $$""" + #nullable enable + using System; using Vogen; - public class C - { - } - - #nullable enable - [ValueObject>] + [ValueObject] public partial {{type}} MyVo; - - #nullable restore """; await new SnapshotRunner() @@ -64,6 +59,33 @@ public class C .RunOn(TargetFramework.Net8_0); } + [Theory] + [InlineData("struct")] + [InlineData("class")] + [InlineData("record struct")] + [InlineData("record class")] + public async Task Nullable_try_parse_if_validation_supplied(string type) + { + var source = + $$""" + #nullable enable + + using System; + using Vogen; + + [ValueObject] + public partial {{type}} MyVo + { + private static Validation Validate(int value) => value > 0 ? Validation.Ok : Validation.Invalid("Must be > 0"); + } + """; + + await new SnapshotRunner() + .WithSource(source) + .CustomizeSettings(s => s.UseFileName(TestHelper.ShortenForFilename($"{nameof(Nullable_try_parse_if_validation_supplied)}{type}"))) + .RunOn(TargetFramework.Net8_0); + } + [Fact] public async Task Can_specify_a_generic_underlying() { diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/3MiocXsMvZ.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/3MiocXsMvZ.verified.txt index d4a46b3306..7ea61ba7d6 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/3MiocXsMvZ.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/3MiocXsMvZ.verified.txt @@ -68,8 +68,8 @@ using Vogen; [global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] -[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: C, Value = { _value }")] -public partial record class MyVo : global::System.IEquatable, global::System.IEquatable> +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +public partial record class MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable { #if DEBUG private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; @@ -77,27 +77,22 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if !VOGEN_NO_VALIDATION private readonly global::System.Boolean _isInitialized; #endif - private readonly C? _value; + private readonly System.Int32 _value; /// - /// Gets the underlying value if set, otherwise a is thrown. + /// Gets the underlying value if set, otherwise a is thrown. /// - public C Value + public System.Int32 Value { [global::System.Diagnostics.DebuggerStepThroughAttribute] get { EnsureInitialized(); - return _value!; + return _value; } [global::System.Diagnostics.DebuggerStepThroughAttribute] init { - if (value is null) - { - throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); - } - _value = value; } } @@ -112,11 +107,11 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if !VOGEN_NO_VALIDATION _isInitialized = false; #endif - _value = default !; + _value = default; } [global::System.Diagnostics.DebuggerStepThroughAttribute] - private MyVo(C value) + private MyVo(System.Int32 value) { _value = value; #if !VOGEN_NO_VALIDATION @@ -129,13 +124,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The underlying type. /// An instance of this type. - public static MyVo From(C value) + public static MyVo From(System.Int32 value) { - if (value is null) - { - throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); - } - MyVo instance = new MyVo(value); return instance; } @@ -155,7 +145,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] #endif - C? value, + System.Int32 value, #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] #endif @@ -163,12 +153,6 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. { - if (value is null) - { - vo = default !; - return false; - } - vo = new MyVo(value); return true; } @@ -180,13 +164,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The primitive value. /// A containing either the value object, or an error. - public static ValueObjectOrError TryFrom(C value) + public static ValueObjectOrError TryFrom(System.Int32 value) { - if (value is null) - { - return new ValueObjectOrError(Validation.Invalid("The value provided was null")); - } - return new ValueObjectOrError(new MyVo(value)); } @@ -204,13 +183,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #endif // only called internally when something has been deserialized into // its primitive type. - private static MyVo __Deserialize(C value) + private static MyVo __Deserialize(System.Int32 value) { - if (value is null) - { - throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); - } - return new MyVo(value); } @@ -230,7 +204,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; return true; } - return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer>.Default.Equals(Value, other.Value); + return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); } public global::System.Boolean Equals(MyVo? other, global::System.Collections.Generic.IEqualityComparer comparer) @@ -238,24 +212,342 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; return comparer.Equals(this, other); } - public global::System.Boolean Equals(C? primitive) + public global::System.Boolean Equals(System.Int32 primitive) { return Value.Equals(primitive); } - public static global::System.Boolean operator ==(MyVo? left, C? right) => left?.Value.Equals(right) ?? false; - public static global::System.Boolean operator ==(C? left, MyVo? right) => right?.Value.Equals(left) ?? false; - public static global::System.Boolean operator !=(C? left, MyVo? right) => !(left == right); - public static global::System.Boolean operator !=(MyVo? left, C? right) => !(left == right); - public static explicit operator MyVo(C value) => From(value); - public static explicit operator C(MyVo value) => value.Value; + public static global::System.Boolean operator ==(MyVo? left, System.Int32 right) => left?.Value.Equals(right) ?? false; + public static global::System.Boolean operator ==(System.Int32 left, MyVo? right) => right?.Value.Equals(left) ?? false; + public static global::System.Boolean operator !=(System.Int32 left, MyVo? right) => !(left == right); + public static global::System.Boolean operator !=(MyVo? left, System.Int32 right) => !(left == right); + public static explicit operator MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; + public int CompareTo(MyVo? other) + { + if (other is null) + return 1; + return Value.CompareTo(other.Value); + } + + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + public override global::System.Int32 GetHashCode() { unchecked // Overflow is fine, just wrap { global::System.Int32 hash = (global::System.Int32)2166136261; hash = (hash * 16777619) ^ GetType().GetHashCode(); - hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer>.Default.GetHashCode(Value); + hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); return hash; } } @@ -278,7 +570,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } // record enumerates fields - we just want our Value and to throw if it's not initialized. - /// Returns the string representation of the underlying . + /// Returns the string representation of the underlying . public override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; #nullable disable /// @@ -288,24 +580,30 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif } public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif } #if NET6_0_OR_GREATER public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); } public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - writer.WritePropertyName(global::System.Text.Json.JsonSerializer.Serialize(value.Value)); + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); } #endif } @@ -316,25 +614,37 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); } public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) { - C ut = (C)value; - return MyVo.__Deserialize(ut); + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; } public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); } public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) { if (value is MyVo idValue) { - return idValue.Value; + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } } return base.ConvertTo(context, culture, value, destinationType); @@ -350,8 +660,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; _t = t; } - public global::System.String UnderlyingType => "C"; - public C Value => _t.Value; + public global::System.String UnderlyingType => "System.Int32"; + public System.Int32 Value => _t.Value; public global::System.String Conversions => @"[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] "; diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/7GTKmGhAq6.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/7GTKmGhAq6.verified.txt new file mode 100644 index 0000000000..6664258651 --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/7GTKmGhAq6.verified.txt @@ -0,0 +1,766 @@ +[ +// ------------------------------------------------------------------------------ +// +// 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> { + { typeof(MyVo), new global::System.Lazy(() => new MyVo.MyVoSystemTextJsonConverter()) } + }; + + 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 +#nullable enable +using Vogen; + +[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] +[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] +[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] +[global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +public partial record struct MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable +{ +#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] + get + { + EnsureInitialized(); + return _value; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + init + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + 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; + } + + _value = value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyVo() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyVo(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. + public static MyVo From(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + 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; + } + + MyVo instance = new MyVo(value); + return instance; + } + + /// + /// 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 MyVo vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + vo = default !; + return false; + } + + vo = new MyVo(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 ValueObjectOrError TryFrom(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + return new ValueObjectOrError(validation); + } + + return new ValueObjectOrError(new MyVo(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if NETCOREAPP3_0_OR_GREATER +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(_value))] +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(Value))] +#endif +#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 MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; + // only called internally when something has been deserialized into + // its primitive type. + private static MyVo __Deserialize(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + throw new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + } + + return new MyVo(value); + } + + public readonly global::System.Boolean Equals(MyVo 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(MyVo 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 static global::System.Boolean operator ==(MyVo left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyVo right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyVo right) => !(left == right); + public static global::System.Boolean operator !=(MyVo left, System.Int32 right) => !(left == right); + public int CompareTo(MyVo other) => Value.CompareTo(other.Value); + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + public readonly override global::System.Int32 GetHashCode() + { + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + } + +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(_value))] + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(Value))] +#endif + private readonly void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + global::System.String message = "Use of uninitialized Value Object at: " + _stackTrace ?? ""; +#else + global::System.String message = "Use of uninitialized Value Object."; +#endif + throw new global::Vogen.ValueObjectValidationException(message); + } + } + + // record enumerates fields - we just want our Value and to throw if it's not initialized. + /// Returns the string representation of the underlying . + public readonly override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; +#nullable disable + /// + /// Converts a MyVo to or from JSON. + /// + public class MyVoSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif + } + + public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif + } +#if NET6_0_OR_GREATER + public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); + } + + public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); + } +#endif + } + +#nullable restore +#nullable disable + class MyVoTypeConverter : global::System.ComponentModel.TypeConverter + { + public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); + } + + public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) + { + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); + } + + public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) + { + if (value is MyVo idValue) + { + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + +#nullable restore +#nullable disable + internal sealed class MyVoDebugView + { + private readonly MyVo _t; + MyVoDebugView(MyVo 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 => @"Default"; + } +#nullable restore +} +#nullable restore + +] \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/CCsypEKKMq.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/CCsypEKKMq.verified.txt new file mode 100644 index 0000000000..7475979050 --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/CCsypEKKMq.verified.txt @@ -0,0 +1,769 @@ +[ +// ------------------------------------------------------------------------------ +// +// 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> { + { typeof(MyVo), new global::System.Lazy(() => new MyVo.MyVoSystemTextJsonConverter()) } + }; + + 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 +#nullable enable +using Vogen; + +[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] +[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] +[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] +[global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +public partial class MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable +{ +#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 System.Int32 Value + { + [global::System.Diagnostics.DebuggerStepThroughAttribute] + get + { + EnsureInitialized(); + return _value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyVo() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default !; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyVo(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. + public static MyVo From(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + 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; + } + + MyVo instance = new MyVo(value); + return instance; + } + + /// + /// 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 MyVo vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + vo = default !; + return false; + } + + vo = new MyVo(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 ValueObjectOrError TryFrom(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + return new ValueObjectOrError(validation); + } + + return new ValueObjectOrError(new MyVo(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if NETCOREAPP3_0_OR_GREATER +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(_value))] +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(Value))] +#endif +#if VOGEN_NO_VALIDATION +#pragma warning disable CS8775 + public bool IsInitialized() => true; +#pragma warning restore CS8775 +#else + public bool IsInitialized() => _isInitialized; +#endif + // only called internally when something has been deserialized into + // its primitive type. + private static MyVo __Deserialize(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + throw new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + } + + return new MyVo(value); + } + + public global::System.Boolean Equals(MyVo? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + // 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; + if (ReferenceEquals(this, other)) + { + return true; + } + + return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); + } + + public global::System.Boolean Equals(MyVo? other, global::System.Collections.Generic.IEqualityComparer comparer) + { + return comparer.Equals(this, other); + } + + public global::System.Boolean Equals(System.Int32 primitive) + { + return Value.Equals(primitive); + } + + public override global::System.Boolean Equals(global::System.Object? obj) + { + return Equals(obj as MyVo); + } + + public static global::System.Boolean operator ==(MyVo? left, MyVo? right) => Equals(left, right); + public static global::System.Boolean operator !=(MyVo? left, MyVo? right) => !Equals(left, right); + public static global::System.Boolean operator ==(MyVo? left, System.Int32 right) => left?.Value.Equals(right) ?? false; + public static global::System.Boolean operator ==(System.Int32 left, MyVo? right) => right?.Value.Equals(left) ?? false; + public static global::System.Boolean operator !=(System.Int32 left, MyVo? right) => !(left == right); + public static global::System.Boolean operator !=(MyVo? left, System.Int32 right) => !(left == right); + public static explicit operator MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; + public int CompareTo(MyVo? other) + { + if (other is null) + return 1; + return Value.CompareTo(other.Value); + } + + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + public override global::System.Int32 GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + global::System.Int32 hash = (global::System.Int32)2166136261; + hash = (hash * 16777619) ^ GetType().GetHashCode(); + hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + return hash; + } + } + +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(_value))] + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(Value))] +#endif + private void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + global::System.String message = "Use of uninitialized Value Object at: " + _stackTrace ?? ""; +#else + global::System.String message = "Use of uninitialized Value Object."; +#endif + throw new global::Vogen.ValueObjectValidationException(message); + } + } + + /// Returns the string representation of the underlying . + public override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; +#nullable disable + /// + /// Converts a MyVo to or from JSON. + /// + public class MyVoSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif + } + + public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif + } +#if NET6_0_OR_GREATER + public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); + } + + public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); + } +#endif + } + +#nullable restore +#nullable disable + class MyVoTypeConverter : global::System.ComponentModel.TypeConverter + { + public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); + } + + public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) + { + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); + } + + public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) + { + if (value is MyVo idValue) + { + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + +#nullable restore + internal sealed class MyVoDebugView + { + private readonly MyVo _t; + MyVoDebugView(MyVo t) + { + _t = t; + } + + public global::System.String UnderlyingType => "System.Int32"; + public System.Int32 Value => _t.Value; + public global::System.String Conversions => @"[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] +[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] +"; + } +} +#nullable restore + +] \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/IF0HerfmAk.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/IF0HerfmAk.verified.txt index 40cc07387b..78386c6d01 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/IF0HerfmAk.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/IF0HerfmAk.verified.txt @@ -68,8 +68,8 @@ using Vogen; [global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] -[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: C, Value = { _value }")] -public partial class MyVo : global::System.IEquatable, global::System.IEquatable> +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +public partial class MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable { #if DEBUG private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; @@ -77,17 +77,17 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if !VOGEN_NO_VALIDATION private readonly global::System.Boolean _isInitialized; #endif - private readonly C? _value; + private readonly System.Int32 _value; /// - /// Gets the underlying value if set, otherwise a is thrown. + /// Gets the underlying value if set, otherwise a is thrown. /// - public C Value + public System.Int32 Value { [global::System.Diagnostics.DebuggerStepThroughAttribute] get { EnsureInitialized(); - return _value!; + return _value; } } @@ -105,7 +105,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } [global::System.Diagnostics.DebuggerStepThroughAttribute] - private MyVo(C value) + private MyVo(System.Int32 value) { _value = value; #if !VOGEN_NO_VALIDATION @@ -118,13 +118,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The underlying type. /// An instance of this type. - public static MyVo From(C value) + public static MyVo From(System.Int32 value) { - if (value is null) - { - throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); - } - MyVo instance = new MyVo(value); return instance; } @@ -144,7 +139,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] #endif - C? value, + System.Int32 value, #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] #endif @@ -152,12 +147,6 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. { - if (value is null) - { - vo = default !; - return false; - } - vo = new MyVo(value); return true; } @@ -169,13 +158,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The primitive value. /// A containing either the value object, or an error. - public static ValueObjectOrError TryFrom(C value) + public static ValueObjectOrError TryFrom(System.Int32 value) { - if (value is null) - { - return new ValueObjectOrError(Validation.Invalid("The value provided was null")); - } - return new ValueObjectOrError(new MyVo(value)); } @@ -193,13 +177,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #endif // only called internally when something has been deserialized into // its primitive type. - private static MyVo __Deserialize(C value) + private static MyVo __Deserialize(System.Int32 value) { - if (value is null) - { - throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); - } - return new MyVo(value); } @@ -219,7 +198,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; return true; } - return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer>.Default.Equals(Value, other.Value); + return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); } public global::System.Boolean Equals(MyVo? other, global::System.Collections.Generic.IEqualityComparer comparer) @@ -227,7 +206,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; return comparer.Equals(this, other); } - public global::System.Boolean Equals(C? primitive) + public global::System.Boolean Equals(System.Int32 primitive) { return Value.Equals(primitive); } @@ -239,19 +218,337 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; public static global::System.Boolean operator ==(MyVo? left, MyVo? right) => Equals(left, right); public static global::System.Boolean operator !=(MyVo? left, MyVo? right) => !Equals(left, right); - public static global::System.Boolean operator ==(MyVo? left, C? right) => left?.Value.Equals(right) ?? false; - public static global::System.Boolean operator ==(C? left, MyVo? right) => right?.Value.Equals(left) ?? false; - public static global::System.Boolean operator !=(C? left, MyVo? right) => !(left == right); - public static global::System.Boolean operator !=(MyVo? left, C? right) => !(left == right); - public static explicit operator MyVo(C value) => From(value); - public static explicit operator C(MyVo value) => value.Value; + public static global::System.Boolean operator ==(MyVo? left, System.Int32 right) => left?.Value.Equals(right) ?? false; + public static global::System.Boolean operator ==(System.Int32 left, MyVo? right) => right?.Value.Equals(left) ?? false; + public static global::System.Boolean operator !=(System.Int32 left, MyVo? right) => !(left == right); + public static global::System.Boolean operator !=(MyVo? left, System.Int32 right) => !(left == right); + public static explicit operator MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; + public int CompareTo(MyVo? other) + { + if (other is null) + return 1; + return Value.CompareTo(other.Value); + } + + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + public override global::System.Int32 GetHashCode() { unchecked // Overflow is fine, just wrap { global::System.Int32 hash = (global::System.Int32)2166136261; hash = (hash * 16777619) ^ GetType().GetHashCode(); - hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer>.Default.GetHashCode(Value); + hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); return hash; } } @@ -273,7 +570,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } } - /// Returns the string representation of the underlying . + /// Returns the string representation of the underlying . public override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; #nullable disable /// @@ -283,24 +580,30 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif } public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif } #if NET6_0_OR_GREATER public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); } public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - writer.WritePropertyName(global::System.Text.Json.JsonSerializer.Serialize(value.Value)); + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); } #endif } @@ -311,25 +614,37 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); } public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) { - C ut = (C)value; - return MyVo.__Deserialize(ut); + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; } public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); } public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) { if (value is MyVo idValue) { - return idValue.Value; + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } } return base.ConvertTo(context, culture, value, destinationType); @@ -345,8 +660,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; _t = t; } - public global::System.String UnderlyingType => "C"; - public C Value => _t.Value; + public global::System.String UnderlyingType => "System.Int32"; + public System.Int32 Value => _t.Value; public global::System.String Conversions => @"[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] "; diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/TTKgwqhtVO.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/TTKgwqhtVO.verified.txt new file mode 100644 index 0000000000..a3e4aac88e --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/TTKgwqhtVO.verified.txt @@ -0,0 +1,752 @@ +[ +// ------------------------------------------------------------------------------ +// +// 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> { + { typeof(MyVo), new global::System.Lazy(() => new MyVo.MyVoSystemTextJsonConverter()) } + }; + + 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 +#nullable enable +using Vogen; + +[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] +[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] +[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] +[global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +// ReSharper disable once UnusedType.Global +public partial struct MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable +{ +#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] + get + { + EnsureInitialized(); + return _value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyVo() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyVo(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. + public static MyVo From(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + 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; + } + + MyVo instance = new MyVo(value); + return instance; + } + + /// + /// 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 MyVo vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + vo = default !; + return false; + } + + vo = new MyVo(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 ValueObjectOrError TryFrom(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + return new ValueObjectOrError(validation); + } + + return new ValueObjectOrError(new MyVo(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if NETCOREAPP3_0_OR_GREATER +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(_value))] +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(Value))] +#endif +#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 MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; + // only called internally when something has been deserialized into + // its primitive type. + private static MyVo __Deserialize(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + throw new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + } + + return new MyVo(value); + } + + public readonly global::System.Boolean Equals(MyVo 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(MyVo 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 MyVo && Equals((MyVo)obj); + } + + public static global::System.Boolean operator ==(MyVo left, MyVo right) => left.Equals(right); + public static global::System.Boolean operator !=(MyVo left, MyVo right) => !(left == right); + public static global::System.Boolean operator ==(MyVo left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyVo right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyVo right) => !(left == right); + public static global::System.Boolean operator !=(MyVo left, System.Int32 right) => !(left == right); + public int CompareTo(MyVo other) => Value.CompareTo(other.Value); + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default; + return false; + } + + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + public readonly override global::System.Int32 GetHashCode() + { + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + } + + /// Returns the string representation of the underlying . + public readonly override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(_value))] + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(Value))] +#endif + private readonly void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + global::System.String message = "Use of uninitialized Value Object at: " + _stackTrace ?? ""; +#else + global::System.String message = "Use of uninitialized Value Object."; +#endif + throw new global::Vogen.ValueObjectValidationException(message); + } + } + +#nullable disable + /// + /// Converts a MyVo to or from JSON. + /// + public class MyVoSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif + } + + public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif + } +#if NET6_0_OR_GREATER + public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); + } + + public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); + } +#endif + } + +#nullable restore +#nullable disable + class MyVoTypeConverter : global::System.ComponentModel.TypeConverter + { + public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); + } + + public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) + { + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); + } + + public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) + { + if (value is MyVo idValue) + { + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + +#nullable restore +#nullable disable + internal sealed class MyVoDebugView + { + private readonly MyVo _t; + MyVoDebugView(MyVo 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 => @"Default"; + } +#nullable restore +} +#nullable restore + +] \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UNEhUoV13X.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UNEhUoV13X.verified.txt index e8c9fe8b26..bd93676af5 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UNEhUoV13X.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UNEhUoV13X.verified.txt @@ -68,8 +68,8 @@ using Vogen; [global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] -[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: C, Value = { _value }")] -public partial record struct MyVo : global::System.IEquatable, global::System.IEquatable> +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +public partial record struct MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable { #if DEBUG private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; @@ -77,27 +77,22 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if !VOGEN_NO_VALIDATION private readonly global::System.Boolean _isInitialized; #endif - private readonly C? _value; + private readonly System.Int32 _value; /// - /// Gets the underlying value if set, otherwise a is thrown. + /// Gets the underlying value if set, otherwise a is thrown. /// - public readonly C Value + public readonly System.Int32 Value { [global::System.Diagnostics.DebuggerStepThroughAttribute] get { EnsureInitialized(); - return _value!; + return _value; } [global::System.Diagnostics.DebuggerStepThroughAttribute] init { - if (value is null) - { - throw new global::Vogen.ValueObjectValidationException("Cannot create a value object with null."); - } - _value = value; } } @@ -116,7 +111,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } [global::System.Diagnostics.DebuggerStepThroughAttribute] - private MyVo(C value) + private MyVo(System.Int32 value) { _value = value; #if !VOGEN_NO_VALIDATION @@ -129,7 +124,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The underlying type. /// An instance of this type. - public static MyVo From(C value) + public static MyVo From(System.Int32 value) { MyVo instance = new MyVo(value); return instance; @@ -150,7 +145,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] #endif - C? value, + System.Int32 value, #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] #endif @@ -158,12 +153,6 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. { - if (value is null) - { - vo = default; - return false; - } - vo = new MyVo(value); return true; } @@ -175,13 +164,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The primitive value. /// A containing either the value object, or an error. - public static ValueObjectOrError TryFrom(C value) + public static ValueObjectOrError TryFrom(System.Int32 value) { - if (value is null) - { - return new ValueObjectOrError(Validation.Invalid("The value provided was null")); - } - return new ValueObjectOrError(new MyVo(value)); } @@ -197,11 +181,11 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #else public readonly bool IsInitialized() => _isInitialized; #endif - public static explicit operator MyVo(C value) => From(value); - public static explicit operator C(MyVo value) => value.Value; + public static explicit operator MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; // only called internally when something has been deserialized into // its primitive type. - private static MyVo __Deserialize(C value) + private static MyVo __Deserialize(System.Int32 value) { return new MyVo(value); } @@ -212,7 +196,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; // 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); + return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); } public global::System.Boolean Equals(MyVo other, global::System.Collections.Generic.IEqualityComparer comparer) @@ -220,18 +204,330 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; return comparer.Equals(this, other); } - public readonly global::System.Boolean Equals(C? primitive) + public readonly global::System.Boolean Equals(System.Int32 primitive) { return Value.Equals(primitive); } - public static global::System.Boolean operator ==(MyVo left, C? right) => left.Value.Equals(right); - public static global::System.Boolean operator ==(C? left, MyVo right) => right.Value.Equals(left); - public static global::System.Boolean operator !=(C? left, MyVo right) => !(left == right); - public static global::System.Boolean operator !=(MyVo left, C? right) => !(left == right); + public static global::System.Boolean operator ==(MyVo left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyVo right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyVo right) => !(left == right); + public static global::System.Boolean operator !=(MyVo left, System.Int32 right) => !(left == right); + public int CompareTo(MyVo other) => Value.CompareTo(other.Value); + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + public readonly override global::System.Int32 GetHashCode() { - return global::System.Collections.Generic.EqualityComparer>.Default.GetHashCode(Value); + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); } #if NETCOREAPP3_0_OR_GREATER @@ -252,7 +548,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } // record enumerates fields - we just want our Value and to throw if it's not initialized. - /// Returns the string representation of the underlying . + /// Returns the string representation of the underlying . public readonly override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; #nullable disable /// @@ -262,24 +558,30 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif } public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif } #if NET6_0_OR_GREATER public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); } public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - writer.WritePropertyName(global::System.Text.Json.JsonSerializer.Serialize(value.Value)); + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); } #endif } @@ -290,25 +592,37 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); } public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) { - C ut = (C)value; - return MyVo.__Deserialize(ut); + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; } public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); } public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) { if (value is MyVo idValue) { - return idValue.Value; + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } } return base.ConvertTo(context, culture, value, destinationType); @@ -326,7 +640,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } public global::System.Boolean IsInitialized => _t.IsInitialized(); - public global::System.String UnderlyingType => "C"; + 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"; diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UspYksUlcS.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UspYksUlcS.verified.txt new file mode 100644 index 0000000000..e24fb601b9 --- /dev/null +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/UspYksUlcS.verified.txt @@ -0,0 +1,784 @@ +[ +// ------------------------------------------------------------------------------ +// +// 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> { + { typeof(MyVo), new global::System.Lazy(() => new MyVo.MyVoSystemTextJsonConverter()) } + }; + + 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 +#nullable enable +using Vogen; + +[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")] +[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] +[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] +[global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] +public partial record class MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable +{ +#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 System.Int32 Value + { + [global::System.Diagnostics.DebuggerStepThroughAttribute] + get + { + EnsureInitialized(); + return _value; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + init + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + 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; + } + + _value = value; + } + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public MyVo() + { +#if DEBUG + _stackTrace = new global::System.Diagnostics.StackTrace(); +#endif +#if !VOGEN_NO_VALIDATION + _isInitialized = false; +#endif + _value = default; + } + + [global::System.Diagnostics.DebuggerStepThroughAttribute] + private MyVo(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. + public static MyVo From(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + 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; + } + + MyVo instance = new MyVo(value); + return instance; + } + + /// + /// 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 MyVo vo) +#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. + + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + vo = default !; + return false; + } + + vo = new MyVo(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 ValueObjectOrError TryFrom(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + return new ValueObjectOrError(validation); + } + + return new ValueObjectOrError(new MyVo(value)); + } + + [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] +#if NETCOREAPP3_0_OR_GREATER +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(_value))] +[global:: System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute(true, nameof(Value))] +#endif +#if VOGEN_NO_VALIDATION +#pragma warning disable CS8775 + public bool IsInitialized() => true; +#pragma warning restore CS8775 +#else + public bool IsInitialized() => _isInitialized; +#endif + // only called internally when something has been deserialized into + // its primitive type. + private static MyVo __Deserialize(System.Int32 value) + { + var validation = MyVo.Validate(value); + if (validation != Vogen.Validation.Ok) + { + throw new global::Vogen.ValueObjectValidationException(validation.ErrorMessage); + } + + return new MyVo(value); + } + + public virtual global::System.Boolean Equals(MyVo? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + // 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; + if (ReferenceEquals(this, other)) + { + return true; + } + + return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); + } + + public global::System.Boolean Equals(MyVo? other, global::System.Collections.Generic.IEqualityComparer comparer) + { + return comparer.Equals(this, other); + } + + public global::System.Boolean Equals(System.Int32 primitive) + { + return Value.Equals(primitive); + } + + public static global::System.Boolean operator ==(MyVo? left, System.Int32 right) => left?.Value.Equals(right) ?? false; + public static global::System.Boolean operator ==(System.Int32 left, MyVo? right) => right?.Value.Equals(left) ?? false; + public static global::System.Boolean operator !=(System.Int32 left, MyVo? right) => !(left == right); + public static global::System.Boolean operator !=(MyVo? left, System.Int32 right) => !(left == right); + public static explicit operator MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; + public int CompareTo(MyVo? other) + { + if (other is null) + return 1; + return Value.CompareTo(other.Value); + } + + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + var validation = MyVo.Validate(__v); + if (validation != Vogen.Validation.Ok) + { + result = default !; + return false; + } + + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + + public override global::System.Int32 GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + global::System.Int32 hash = (global::System.Int32)2166136261; + hash = (hash * 16777619) ^ GetType().GetHashCode(); + hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); + return hash; + } + } + +#if NETCOREAPP3_0_OR_GREATER + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(_value))] + [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(Value))] +#endif + private void EnsureInitialized() + { + if (!IsInitialized()) + { +#if DEBUG + global::System.String message = "Use of uninitialized Value Object at: " + _stackTrace ?? ""; +#else + global::System.String message = "Use of uninitialized Value Object."; +#endif + throw new global::Vogen.ValueObjectValidationException(message); + } + } + + // record enumerates fields - we just want our Value and to throw if it's not initialized. + /// Returns the string representation of the underlying . + public override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; +#nullable disable + /// + /// Converts a MyVo to or from JSON. + /// + public class MyVoSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter + { + public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif + } + + public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif + } +#if NET6_0_OR_GREATER + public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) + { + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); + } + + public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) + { + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); + } +#endif + } + +#nullable restore +#nullable disable + class MyVoTypeConverter : global::System.ComponentModel.TypeConverter + { + public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); + } + + public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) + { + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; + } + + public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) + { + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); + } + + public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) + { + if (value is MyVo idValue) + { + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } + } + + return base.ConvertTo(context, culture, value, destinationType); + } + } + +#nullable restore + internal sealed class MyVoDebugView + { + private readonly MyVo _t; + MyVoDebugView(MyVo t) + { + _t = t; + } + + public global::System.String UnderlyingType => "System.Int32"; + public System.Int32 Value => _t.Value; + public global::System.String Conversions => @"[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] +[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] +"; + } +} +#nullable restore + +] \ No newline at end of file diff --git a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/rVLQH7WZJe.verified.txt b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/rVLQH7WZJe.verified.txt index cd75789cf1..2c50114d76 100644 --- a/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/rVLQH7WZJe.verified.txt +++ b/tests/SnapshotTests/GeneralStuff/snapshots/snap-v8.0/rVLQH7WZJe.verified.txt @@ -68,9 +68,9 @@ using Vogen; [global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))] [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))] [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))] -[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: C, Value = { _value }")] +[global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.Int32, Value = { _value }")] // ReSharper disable once UnusedType.Global -public partial struct MyVo : global::System.IEquatable, global::System.IEquatable> +public partial struct MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable { #if DEBUG private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; @@ -78,17 +78,17 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if !VOGEN_NO_VALIDATION private readonly global::System.Boolean _isInitialized; #endif - private readonly C? _value; + private readonly System.Int32 _value; /// - /// Gets the underlying value if set, otherwise a is thrown. + /// Gets the underlying value if set, otherwise a is thrown. /// - public readonly C Value + public readonly System.Int32 Value { [global::System.Diagnostics.DebuggerStepThroughAttribute] get { EnsureInitialized(); - return _value!; + return _value; } } @@ -106,7 +106,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } [global::System.Diagnostics.DebuggerStepThroughAttribute] - private MyVo(C value) + private MyVo(System.Int32 value) { _value = value; #if !VOGEN_NO_VALIDATION @@ -119,7 +119,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The underlying type. /// An instance of this type. - public static MyVo From(C value) + public static MyVo From(System.Int32 value) { MyVo instance = new MyVo(value); return instance; @@ -140,7 +140,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] #endif - C? value, + System.Int32 value, #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] #endif @@ -148,12 +148,6 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes. { - if (value is null) - { - vo = default; - return false; - } - vo = new MyVo(value); return true; } @@ -165,13 +159,8 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; /// /// The primitive value. /// A containing either the value object, or an error. - public static ValueObjectOrError TryFrom(C value) + public static ValueObjectOrError TryFrom(System.Int32 value) { - if (value is null) - { - return new ValueObjectOrError(Validation.Invalid("The value provided was null")); - } - return new ValueObjectOrError(new MyVo(value)); } @@ -187,11 +176,11 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; #else public readonly bool IsInitialized() => _isInitialized; #endif - public static explicit operator MyVo(C value) => From(value); - public static explicit operator C(MyVo value) => value.Value; + public static explicit operator MyVo(System.Int32 value) => From(value); + public static explicit operator System.Int32(MyVo value) => value.Value; // only called internally when something has been deserialized into // its primitive type. - private static MyVo __Deserialize(C value) + private static MyVo __Deserialize(System.Int32 value) { return new MyVo(value); } @@ -202,7 +191,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; // 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); + return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value); } public global::System.Boolean Equals(MyVo other, global::System.Collections.Generic.IEqualityComparer comparer) @@ -210,7 +199,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; return comparer.Equals(this, other); } - public readonly global::System.Boolean Equals(C? primitive) + public readonly global::System.Boolean Equals(System.Int32 primitive) { return Value.Equals(primitive); } @@ -222,16 +211,328 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; public static global::System.Boolean operator ==(MyVo left, MyVo right) => left.Equals(right); public static global::System.Boolean operator !=(MyVo left, MyVo right) => !(left == right); - public static global::System.Boolean operator ==(MyVo left, C? right) => left.Value.Equals(right); - public static global::System.Boolean operator ==(C? left, MyVo right) => right.Value.Equals(left); - public static global::System.Boolean operator !=(C? left, MyVo right) => !(left == right); - public static global::System.Boolean operator !=(MyVo left, C? right) => !(left == right); + public static global::System.Boolean operator ==(MyVo left, System.Int32 right) => left.Value.Equals(right); + public static global::System.Boolean operator ==(System.Int32 left, MyVo right) => right.Value.Equals(left); + public static global::System.Boolean operator !=(System.Int32 left, MyVo right) => !(left == right); + public static global::System.Boolean operator !=(MyVo left, System.Int32 right) => !(left == right); + public int CompareTo(MyVo other) => Value.CompareTo(other.Value); + public int CompareTo(object? other) + { + if (other is null) + return 1; + if (other is MyVo x) + return CompareTo(x); + throw new global::System.ArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other)); + } + + /// + /// + /// + /// + /// 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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(utf8Text, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, style, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, provider, out var __v)) + { + result = new MyVo(__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 MyVo result) + { + if (System.Int32.TryParse(s, out var __v)) + { + result = new MyVo(__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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo 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 MyVo Parse(string s, global::System.IFormatProvider? provider) + { + var r = System.Int32.Parse(s, provider); + return From(r); + } + public readonly override global::System.Int32 GetHashCode() { - return global::System.Collections.Generic.EqualityComparer>.Default.GetHashCode(Value); + return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value); } - /// Returns the string representation of the underlying . + /// Returns the string representation of the underlying . public readonly override global::System.String? ToString() => IsInitialized() ? Value.ToString() : "[UNINITIALIZED]"; #if NETCOREAPP3_0_OR_GREATER [global::System.Diagnostics.CodeAnalysis.MemberNotNullAttribute(nameof(_value))] @@ -258,24 +559,30 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); +#if NET5_0_OR_GREATER + return MyVo.__Deserialize(global::System.Text.Json.JsonSerializer.Deserialize(ref reader, (global::System.Text.Json.Serialization.Metadata.JsonTypeInfo)options.GetTypeInfo(typeof(global::System.Int32)))); +#else + return MyVo.__Deserialize(reader.GetInt32()); +#endif } public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#if NET5_0_OR_GREATER + global::System.Text.Json.JsonSerializer.Serialize(writer, value.Value, options); +#else + writer.WriteNumberValue(value.Value); +#endif } #if NET6_0_OR_GREATER public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) { - var primitive = global::System.Text.Json.JsonSerializer.Deserialize>(ref reader, options); - return MyVo.__Deserialize(primitive); + return MyVo.__Deserialize(global::System.Int32.Parse(reader.GetString(), global::System.Globalization.NumberStyles.Any, global::System.Globalization.CultureInfo.InvariantCulture)); } public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options) { - writer.WritePropertyName(global::System.Text.Json.JsonSerializer.Serialize(value.Value)); + writer.WritePropertyName(value.Value.ToString(global::System.Globalization.CultureInfo.InvariantCulture)); } #endif } @@ -286,25 +593,37 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; { public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType); } public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value) { - C ut = (C)value; - return MyVo.__Deserialize(ut); + return value switch + { + global::System.Int32 intValue => MyVo.__Deserialize(intValue), + global::System.String stringValue when !global::System.String.IsNullOrEmpty(stringValue) && global::System.Int32.TryParse(stringValue, out var result) => MyVo.__Deserialize(result), + _ => base.ConvertFrom(context, culture, value), + }; } public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType) { - return sourceType == typeof(C); + return sourceType == typeof(global::System.Int32) || sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType); } public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType) { if (value is MyVo idValue) { - return idValue.Value; + if (destinationType == typeof(global::System.Int32)) + { + return idValue.Value; + } + + if (destinationType == typeof(global::System.String)) + { + return idValue.Value.ToString(); + } } return base.ConvertTo(context, culture, value, destinationType); @@ -322,7 +641,7 @@ private readonly global::System.Diagnostics.StackTrace? _stackTrace = null!; } public global::System.Boolean IsInitialized => _t.IsInitialized(); - public global::System.String UnderlyingType => "C"; + 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";