Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(#68) implemented explicit and implicit casts #81

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
12 changes: 12 additions & 0 deletions src/StronglyTypedIds.Attributes/StronglyTypedIdImplementations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,17 @@ public enum StronglyTypedIdImplementations
/// Implement the <see cref="IComparable{T}"/> interface
/// </summary>
IComparable = 4,

// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement an explicit cast
/// </summary>
ExplicitCast = 8,

// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement an explicit cast
/// </summary>
ImplicitCast = 16,
}
}
18 changes: 18 additions & 0 deletions src/StronglyTypedIds/EmbeddedSources.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_ImplicitCast.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Guid.Guid_ExplicitCast.cs"),
false
);

Expand All @@ -37,6 +39,8 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_ImplicitCast.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Int.Int_ExplicitCast.cs"),
false
);

Expand All @@ -49,6 +53,8 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_ImplicitCast.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.Long.Long_ExplicitCast.cs"),
false
);

Expand All @@ -61,6 +67,8 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_ImplicitCast.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.String.String_ExplicitCast.cs"),
false
);

Expand All @@ -73,6 +81,8 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_ImplicitCast.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NullableString.NullableString_ExplicitCast.cs"),
true
);

Expand All @@ -85,6 +95,8 @@ internal static class EmbeddedSources
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_EfCoreValueConverter.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_DapperTypeHandler.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_IComparable.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_ImplicitCast.cs"),
LoadEmbeddedResource("StronglyTypedIds.Templates.NewId.NewId_ExplicitCast.cs"),
false
);

Expand Down Expand Up @@ -117,6 +129,8 @@ public readonly struct ResourceCollection
public string EfCoreValueConverter { get; }
public string DapperTypeHandler { get; }
public string Comparable { get; }
public string ImplicitCast { get; }
public string ExplicitCast { get; }

public ResourceCollection(
string header,
Expand All @@ -127,6 +141,8 @@ public ResourceCollection(
string efCoreValueConverter,
string dapperTypeHandler,
string comparable,
string implicitCast,
string explicitCast,
bool nullableEnable)
{
BaseId = baseId;
Expand All @@ -136,6 +152,8 @@ public ResourceCollection(
EfCoreValueConverter = efCoreValueConverter;
DapperTypeHandler = dapperTypeHandler;
Comparable = comparable;
ImplicitCast = implicitCast;
ExplicitCast = explicitCast;
NullableEnable = nullableEnable;
Header = header;
}
Expand Down
17 changes: 17 additions & 0 deletions src/StronglyTypedIds/SourceGenerationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,14 @@ static string CreateId(

var useIEquatable = implementations.IsSet(StronglyTypedIdImplementations.IEquatable);
var useIComparable = implementations.IsSet(StronglyTypedIdImplementations.IComparable);
var useImplicitCast = implementations.IsSet(StronglyTypedIdImplementations.ImplicitCast);
var useExplicitCast = implementations.IsSet(StronglyTypedIdImplementations.ExplicitCast);

if (useImplicitCast && useExplicitCast)
{
throw new ArgumentException("Cannot use implicit cast and explicit cast at the same time. Chose only one.", nameof(implementations));
}

var parentsCount = 0;

sb ??= new StringBuilder();
Expand Down Expand Up @@ -132,6 +139,16 @@ static string CreateId(
sb.AppendLine(resources.Comparable);
}

if (useImplicitCast)
{
sb.AppendLine(resources.ImplicitCast);
}

if (useExplicitCast)
{
sb.AppendLine(resources.ExplicitCast);
}

if (useEfCoreValueConverter)
{
sb.AppendLine(resources.EfCoreValueConverter);
Expand Down
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/Guid/Guid_ExplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static explicit operator System.Guid(TESTID id) => id.Value;
public static explicit operator TESTID(System.Guid value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/Guid/Guid_ImplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static implicit operator System.Guid(TESTID id) => id.Value;
public static implicit operator TESTID(System.Guid value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/Int/Int_ExplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static explicit operator int(TESTID id) => id.Value;
public static explicit operator TESTID(int value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/Int/Int_ImplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static implicit operator int(TESTID id) => id.Value;
public static implicit operator TESTID(int value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/Long/Long_ExplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static explicit operator long(TESTID id) => id.Value;
public static explicit operator TESTID(long value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/Long/Long_ImplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static implicit operator long(TESTID id) => id.Value;
public static implicit operator TESTID(long value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/NewId/NewId_ExplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static explicit operator MassTransit.NewId(TESTID id) => id.Value;
public static explicit operator TESTID(MassTransit.NewId value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/NewId/NewId_ImplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static implicit operator MassTransit.NewId(TESTID id) => id.Value;
public static implicit operator TESTID(MassTransit.NewId value) => new(value);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static explicit operator string?(TESTID id) => id.Value;
public static explicit operator TESTID(string? value) => new(value);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static implicit operator string?(TESTID id) => id.Value;
public static implicit operator TESTID(string? value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/String/String_ExplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static explicit operator string(TESTID id) => id.Value;
public static explicit operator TESTID(string value) => new(value);
2 changes: 2 additions & 0 deletions src/StronglyTypedIds/Templates/String/String_ImplicitCast.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
 public static implicit operator string(TESTID id) => id.Value;
public static implicit operator TESTID(string value) => new(value);
17 changes: 17 additions & 0 deletions test/StronglyTypedIds.IntegrationTests/GuidIdTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,23 @@ public void ImplementsInterfaces()
#pragma warning restore 184
}

[Fact]
public void CanExplicitCast()
{
Assert.IsAssignableFrom<ExplicitCastGuidId>((ExplicitCastGuidId)Guid.NewGuid());
Assert.IsAssignableFrom<Guid>((Guid)ExplicitCastGuidId.New());
}

[Fact]
public void CanImplicitCast()
{
ImplicitCastGuidId castedId = Guid.NewGuid();
Assert.IsType<ImplicitCastGuidId>(castedId);

Guid castedGuid = ImplicitCastGuidId.New();
Assert.IsType<Guid>(castedGuid);
}

#if NET6_0_OR_GREATER
[Fact]
public void WhenConventionBasedEfCoreValueConverterUsesValueConverter()
Expand Down
6 changes: 6 additions & 0 deletions test/StronglyTypedIds.IntegrationTests/Types/GuidId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ public partial struct EquatableGuidId { }

[StronglyTypedId(implementations: StronglyTypedIdImplementations.IComparable)]
public partial struct ComparableGuidId { }

[StronglyTypedId(implementations: StronglyTypedIdImplementations.ExplicitCast)]
public partial struct ExplicitCastGuidId { }

[StronglyTypedId(implementations: StronglyTypedIdImplementations.ImplicitCast)]
public partial struct ImplicitCastGuidId { }
}
13 changes: 11 additions & 2 deletions test/StronglyTypedIds.Tests/EnumHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ public static IEnumerable<StronglyTypedIdConverter> AllConverters(bool includeDe
}
}

public static IEnumerable<StronglyTypedIdImplementations> AllImplementations(bool includeDefault = true, bool includeNone = true)
public static IEnumerable<StronglyTypedIdImplementations> AllImplementations(
bool includeDefault = true,
bool includeNone = true,
StronglyTypedIdImplementations[] skip = null,
StronglyTypedIdImplementations[] only = null)
{
skip ??= Array.Empty<StronglyTypedIdImplementations>();
only ??= Array.Empty<StronglyTypedIdImplementations>();

// get highest value
var highestValue = Enum.GetValues(typeof(StronglyTypedIdImplementations))
.Cast<int>()
Expand All @@ -50,7 +57,9 @@ public static IEnumerable<StronglyTypedIdImplementations> AllImplementations(boo
{
var implementations = (StronglyTypedIdImplementations)i;
if (implementations.IsSet(StronglyTypedIdImplementations.Default) && !includeDefault
|| implementations == StronglyTypedIdImplementations.None && !includeNone)
|| implementations == StronglyTypedIdImplementations.None && !includeNone
|| skip.Any(s => implementations.IsSet(s))
|| (only.Length > 0 && !only.Any(s => implementations.IsSet(s))))
{
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ namespace StronglyTypedIds
/// Implement the <see cref="IComparable{T}"/> interface
/// </summary>
IComparable = 4,

// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement an explicit cast
/// </summary>
ExplicitCast = 8,

// ReSharper disable once InconsistentNaming
/// <summary>
/// Implement an explicit cast
/// </summary>
ImplicitCast = 16,
}
}
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the StronglyTypedId source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

namespace Some.Namespace
{
readonly partial struct MyTestId : System.IEquatable<MyTestId>
{
public System.Guid Value { get; }

public MyTestId(System.Guid value)
{
Value = value;
}

public static MyTestId New() => new MyTestId(System.Guid.NewGuid());
public static readonly MyTestId Empty = new MyTestId(System.Guid.Empty);

public bool Equals(MyTestId other) => this.Value.Equals(other.Value);
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is MyTestId other && Equals(other);
}

public override int GetHashCode() => Value.GetHashCode();

public override string ToString() => Value.ToString();
public static bool operator ==(MyTestId a, MyTestId b) => a.Equals(b);
public static bool operator !=(MyTestId a, MyTestId b) => !(a == b);
public static explicit operator System.Guid(MyTestId id) => id.Value;
public static explicit operator MyTestId(System.Guid value) => new(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the StronglyTypedId source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

namespace Some.Namespace
{
readonly partial struct MyTestId : System.IComparable<MyTestId>
{
public System.Guid Value { get; }

public MyTestId(System.Guid value)
{
Value = value;
}

public static MyTestId New() => new MyTestId(System.Guid.NewGuid());
public static readonly MyTestId Empty = new MyTestId(System.Guid.Empty);

public bool Equals(MyTestId other) => this.Value.Equals(other.Value);
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is MyTestId other && Equals(other);
}

public override int GetHashCode() => Value.GetHashCode();

public override string ToString() => Value.ToString();
public static bool operator ==(MyTestId a, MyTestId b) => a.Equals(b);
public static bool operator !=(MyTestId a, MyTestId b) => !(a == b);
public int CompareTo(MyTestId other) => Value.CompareTo(other.Value);
public static explicit operator System.Guid(MyTestId id) => id.Value;
public static explicit operator MyTestId(System.Guid value) => new(value);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by the StronglyTypedId source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#pragma warning disable 1591 // publicly visible type or member must be documented

namespace Some.Namespace
{
readonly partial struct MyTestId : System.IComparable<MyTestId>, System.IEquatable<MyTestId>
{
public System.Guid Value { get; }

public MyTestId(System.Guid value)
{
Value = value;
}

public static MyTestId New() => new MyTestId(System.Guid.NewGuid());
public static readonly MyTestId Empty = new MyTestId(System.Guid.Empty);

public bool Equals(MyTestId other) => this.Value.Equals(other.Value);
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is MyTestId other && Equals(other);
}

public override int GetHashCode() => Value.GetHashCode();

public override string ToString() => Value.ToString();
public static bool operator ==(MyTestId a, MyTestId b) => a.Equals(b);
public static bool operator !=(MyTestId a, MyTestId b) => !(a == b);
public int CompareTo(MyTestId other) => Value.CompareTo(other.Value);
public static explicit operator System.Guid(MyTestId id) => id.Value;
public static explicit operator MyTestId(System.Guid value) => new(value);
}
}
Loading