From 9bc2fdf943876572f0f7980b543af7a481df09b2 Mon Sep 17 00:00:00 2001 From: Andrew Lock Date: Fri, 1 Dec 2023 21:17:17 +0000 Subject: [PATCH] Add support for IUtf8SpanFormattable and IUtf8SpanParsable --- .../guid-full.typedid | 13 +++++++ .../int-full.typedid | 36 ++++++++++++++++-- .../long-full.typedid | 37 +++++++++++++++++-- src/StronglyTypedIds/EmbeddedSources.Guid.cs | 13 +++++++ src/StronglyTypedIds/EmbeddedSources.Int.cs | 34 ++++++++++++++++- src/StronglyTypedIds/EmbeddedSources.Long.cs | 30 +++++++++++++++ .../GuidIdTests.cs | 17 +++++++++ .../IntIdTests.cs | 16 ++++++++ .../LongIdTests.cs | 16 ++++++++ ...ateDefaultIdInGlobalNamespace.verified.txt | 13 +++++++ ...yNestedIdInFileScopeNamespace.verified.txt | 13 +++++++ ...nerateIdInFileScopedNamespace.verified.txt | 13 +++++++ ...ests.CanGenerateIdInNamespace.verified.txt | 13 +++++++ ...nerateMultipleIdsWithSameName.verified.txt | 26 +++++++++++++ ...eMultipleTemplatesWithBuiltIn.verified.txt | 13 +++++++ ...eNestedIdInFileScopeNamespace.verified.txt | 13 +++++++ ...nerateNonDefaultIdInNamespace.verified.txt | 34 ++++++++++++++++- ...yNestedIdInFileScopeNamespace.verified.txt | 13 +++++++ ...hTemplateUsingGlobalAttribute.verified.txt | 34 ++++++++++++++++- 19 files changed, 384 insertions(+), 13 deletions(-) diff --git a/src/StronglyTypedIds.Templates/guid-full.typedid b/src/StronglyTypedIds.Templates/guid-full.typedid index 00a1d2f4..5a0bd951 100644 --- a/src/StronglyTypedIds.Templates/guid-full.typedid +++ b/src/StronglyTypedIds.Templates/guid-full.typedid @@ -7,6 +7,9 @@ #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -203,6 +206,16 @@ global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); #endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); +#endif public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler { diff --git a/src/StronglyTypedIds.Templates/int-full.typedid b/src/StronglyTypedIds.Templates/int-full.typedid index 7fb41986..4cf8cbbe 100644 --- a/src/StronglyTypedIds.Templates/int-full.typedid +++ b/src/StronglyTypedIds.Templates/int-full.typedid @@ -7,6 +7,9 @@ #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -136,7 +139,7 @@ /// public string ToString( #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif string? format, global::System.IFormatProvider? formatProvider) @@ -182,7 +185,7 @@ global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format, global::System.IFormatProvider? provider) @@ -193,11 +196,38 @@ global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); #endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static PLACEHOLDERID Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(int.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out PLACEHOLDERID result) + { + if (int.TryParse(utf8Text, provider, out var intResult)) + { + result = new PLACEHOLDERID(intResult); + return true; + } + + result = default; + return false; + } +#endif public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler { diff --git a/src/StronglyTypedIds.Templates/long-full.typedid b/src/StronglyTypedIds.Templates/long-full.typedid index 616e8a25..e6c61cc9 100644 --- a/src/StronglyTypedIds.Templates/long-full.typedid +++ b/src/StronglyTypedIds.Templates/long-full.typedid @@ -7,6 +7,9 @@ #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -136,7 +139,7 @@ /// public string ToString( #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif string? format, global::System.IFormatProvider? formatProvider) @@ -182,7 +185,7 @@ global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format, global::System.IFormatProvider? provider) @@ -193,12 +196,38 @@ global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); #endif - +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static PLACEHOLDERID Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(long.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out PLACEHOLDERID result) + { + if (long.TryParse(utf8Text, provider, out var intResult)) + { + result = new PLACEHOLDERID(intResult); + return true; + } + + result = default; + return false; + } +#endif public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler { public override void SetValue(global::System.Data.IDbDataParameter parameter, PLACEHOLDERID value) diff --git a/src/StronglyTypedIds/EmbeddedSources.Guid.cs b/src/StronglyTypedIds/EmbeddedSources.Guid.cs index 63ca8556..2eaa0942 100644 --- a/src/StronglyTypedIds/EmbeddedSources.Guid.cs +++ b/src/StronglyTypedIds/EmbeddedSources.Guid.cs @@ -9,6 +9,9 @@ partial struct PLACEHOLDERID : #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, + #endif + #if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -204,6 +207,16 @@ public bool TryFormat( #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); + #endif + #if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } """; diff --git a/src/StronglyTypedIds/EmbeddedSources.Int.cs b/src/StronglyTypedIds/EmbeddedSources.Int.cs index 2690ad76..691aece6 100644 --- a/src/StronglyTypedIds/EmbeddedSources.Int.cs +++ b/src/StronglyTypedIds/EmbeddedSources.Int.cs @@ -9,6 +9,9 @@ partial struct PLACEHOLDERID : #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, + #endif + #if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -184,7 +187,7 @@ public bool TryFormat( global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format, global::System.IFormatProvider? provider) @@ -195,10 +198,37 @@ public bool TryFormat( global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); + #endif + #if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static PLACEHOLDERID Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(int.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out PLACEHOLDERID result) + { + if (int.TryParse(utf8Text, provider, out var intResult)) + { + result = new PLACEHOLDERID(intResult); + return true; + } + + result = default; + return false; + } #endif } """; diff --git a/src/StronglyTypedIds/EmbeddedSources.Long.cs b/src/StronglyTypedIds/EmbeddedSources.Long.cs index c3a3bd3f..d354a398 100644 --- a/src/StronglyTypedIds/EmbeddedSources.Long.cs +++ b/src/StronglyTypedIds/EmbeddedSources.Long.cs @@ -9,6 +9,9 @@ partial struct PLACEHOLDERID : #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, + #endif + #if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -199,6 +202,33 @@ public bool TryFormat( #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); + #endif + #if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static PLACEHOLDERID Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(long.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out PLACEHOLDERID result) + { + if (long.TryParse(utf8Text, provider, out var intResult)) + { + result = new PLACEHOLDERID(intResult); + return true; + } + + result = default; + return false; + } #endif } """; diff --git a/test/StronglyTypedIds.IntegrationTests/GuidIdTests.cs b/test/StronglyTypedIds.IntegrationTests/GuidIdTests.cs index 49460b9b..13a1619a 100644 --- a/test/StronglyTypedIds.IntegrationTests/GuidIdTests.cs +++ b/test/StronglyTypedIds.IntegrationTests/GuidIdTests.cs @@ -75,6 +75,23 @@ public void CantCreateEmptyGeneratedId1() Assert.NotEqual((object)bar, (object)foo); } +#if NET8_0_OR_GREATER + [Fact] + public void CanFormatAsUtf8() + { + var expected = "17b4c96b-023a-4050-8ab5-4511c0e7fd09"u8; + var id = GuidId1.Parse("17B4C96B-023A-4050-8AB5-4511C0E7FD09"); + + var format = "D"; // in expected format + var actual = new byte[expected.Length].AsSpan(); + var success = id.TryFormat(actual, out var charsWritten, format, provider: null); + + Assert.True(success); + Assert.Equal(expected.Length, charsWritten); + Assert.True(actual.SequenceEqual(expected)); + } +#endif + [Fact] public void CanSerializeToGuid_WithTypeConverter() { diff --git a/test/StronglyTypedIds.IntegrationTests/IntIdTests.cs b/test/StronglyTypedIds.IntegrationTests/IntIdTests.cs index b930c312..49406f96 100644 --- a/test/StronglyTypedIds.IntegrationTests/IntIdTests.cs +++ b/test/StronglyTypedIds.IntegrationTests/IntIdTests.cs @@ -66,6 +66,22 @@ public void DifferentTypesAreUnequal() Assert.NotEqual((object) bar, (object) foo); } +#if NET8_0_OR_GREATER + [Fact] + public void CanRoundTripUtf8() + { + var id = new IntId(123); + + var actual = new byte[16].AsSpan(); + Assert.True(id.TryFormat(actual, out var charsWritten)); + + var success = IntId.TryParse(actual.Slice(0, charsWritten), provider: null, out var result); + + Assert.True(success); + Assert.Equal(id, result); + } +#endif + [Fact] public void CanSerializeToNullableInt_WithNewtonsoftJsonProvider() { diff --git a/test/StronglyTypedIds.IntegrationTests/LongIdTests.cs b/test/StronglyTypedIds.IntegrationTests/LongIdTests.cs index 0c078731..e7559da4 100644 --- a/test/StronglyTypedIds.IntegrationTests/LongIdTests.cs +++ b/test/StronglyTypedIds.IntegrationTests/LongIdTests.cs @@ -65,6 +65,22 @@ public void DifferentTypesAreUnequal() Assert.NotEqual((object)bar, (object)foo); } +#if NET8_0_OR_GREATER + [Fact] + public void CanRoundTripUtf8() + { + var id = new LongId(123L); + + var actual = new byte[16].AsSpan(); + Assert.True(id.TryFormat(actual, out var charsWritten)); + + var success = LongId.TryParse(actual.Slice(0, charsWritten), provider: null, out var result); + + Assert.True(success); + Assert.Equal(id, result); + } +#endif + [Fact] public void CanSerializeToNullableInt_WithNewtonsoftJsonProvider() { diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateDefaultIdInGlobalNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateDefaultIdInGlobalNamespace.verified.txt index 4986c71f..495c6135 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateDefaultIdInGlobalNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateDefaultIdInGlobalNamespace.verified.txt @@ -18,6 +18,9 @@ #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -213,5 +216,15 @@ #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateGenericVeryNestedIdInFileScopeNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateGenericVeryNestedIdInFileScopeNamespace.verified.txt index c55e78c8..1720d616 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateGenericVeryNestedIdInFileScopeNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateGenericVeryNestedIdInFileScopeNamespace.verified.txt @@ -24,6 +24,9 @@ namespace SomeNamespace #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -219,6 +222,16 @@ namespace SomeNamespace #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInFileScopedNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInFileScopedNamespace.verified.txt index 8a853037..460539dc 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInFileScopedNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInFileScopedNamespace.verified.txt @@ -20,6 +20,9 @@ namespace SomeNamespace #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -215,6 +218,16 @@ namespace SomeNamespace #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInNamespace.verified.txt index 8a853037..460539dc 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInNamespace.verified.txt @@ -20,6 +20,9 @@ namespace SomeNamespace #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -215,6 +218,16 @@ namespace SomeNamespace #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleIdsWithSameName.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleIdsWithSameName.verified.txt index 9da3f105..7b773035 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleIdsWithSameName.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleIdsWithSameName.verified.txt @@ -20,6 +20,9 @@ namespace MyContracts.V1 #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -215,6 +218,16 @@ namespace MyContracts.V1 #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } @@ -241,6 +254,9 @@ namespace MyContracts.V2 #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -436,6 +452,16 @@ namespace MyContracts.V2 #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt index ddcee0c2..0a816224 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt @@ -77,6 +77,9 @@ #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -272,5 +275,15 @@ #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt index c2b59d42..c605ce0f 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt @@ -22,6 +22,9 @@ namespace SomeNamespace #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -217,6 +220,16 @@ namespace SomeNamespace #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt index db87dacf..692be3d9 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt @@ -20,6 +20,9 @@ namespace SomeNamespace #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -195,7 +198,7 @@ namespace SomeNamespace global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format, global::System.IFormatProvider? provider) @@ -206,10 +209,37 @@ namespace SomeNamespace global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(int.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out MyId result) + { + if (int.TryParse(utf8Text, provider, out var intResult)) + { + result = new MyId(intResult); + return true; + } + + result = default; + return false; + } #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateVeryNestedIdInFileScopeNamespace.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateVeryNestedIdInFileScopeNamespace.verified.txt index 776fbf1d..42c88594 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateVeryNestedIdInFileScopeNamespace.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateVeryNestedIdInFileScopeNamespace.verified.txt @@ -26,6 +26,9 @@ namespace SomeNamespace #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -221,6 +224,16 @@ namespace SomeNamespace #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + global::System.ReadOnlySpan format, + global::System.IFormatProvider? provider) + => Value.TryFormat(utf8Destination, out bytesWritten, format); #endif } } diff --git a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanOverrideDefaultsWithTemplateUsingGlobalAttribute.verified.txt b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanOverrideDefaultsWithTemplateUsingGlobalAttribute.verified.txt index 6e458d2f..38ac4604 100644 --- a/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanOverrideDefaultsWithTemplateUsingGlobalAttribute.verified.txt +++ b/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanOverrideDefaultsWithTemplateUsingGlobalAttribute.verified.txt @@ -18,6 +18,9 @@ #endif #if NET7_0_OR_GREATER global::System.IParsable, global::System.ISpanParsable, +#endif +#if NET8_0_OR_GREATER + global::System.IUtf8SpanParsable, global::System.IUtf8SpanFormattable, #endif global::System.IComparable, global::System.IEquatable, global::System.IFormattable { @@ -193,7 +196,7 @@ global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format, global::System.IFormatProvider? provider) @@ -204,9 +207,36 @@ global::System.Span destination, out int charsWritten, #if NET7_0_OR_GREATER - [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] #endif global::System.ReadOnlySpan format = default) => Value.TryFormat(destination, out charsWritten, format); +#endif +#if NET8_0_OR_GREATER + /// + public bool TryFormat( + global::System.Span utf8Destination, + out int bytesWritten, + [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)] + global::System.ReadOnlySpan format = default, + global::System.IFormatProvider? provider = null) + => Value.TryFormat(utf8Destination, out bytesWritten, format, provider); + + /// + public static MyId Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider) + => new(int.Parse(utf8Text, provider)); + + /// + public static bool TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider? provider, out MyId result) + { + if (int.TryParse(utf8Text, provider, out var intResult)) + { + result = new MyId(intResult); + return true; + } + + result = default; + return false; + } #endif }