Skip to content

Commit 1bdc3cf

Browse files
committed
Add support for string identifiers.
1 parent 39c272c commit 1bdc3cf

13 files changed

+1748
-65
lines changed

Diff for: src/LightResults.Extensions.GeneratedIdentifier/GeneratedIdentifierSourceGenerator.cs

+105-55
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ private static bool Filter(SyntaxNode syntaxNode, CancellationToken cancellation
9494
declaredValueType = "long";
9595
fullValueType = "Int64";
9696
break;
97+
case SpecialType.System_String:
98+
declaredValueType = "string";
99+
fullValueType = "String";
100+
break;
97101
default:
98102
if (typeArgument is not { Name: "Guid", ContainingNamespace: { Name: "System", ContainingNamespace.IsGlobalNamespace: true } })
99103
return null;
@@ -153,7 +157,16 @@ namespace {structNamespace};
153157
[JsonConverter(typeof({{structName}}JsonConverter))]
154158
readonly partial struct {{structName}} :
155159
ICreatableValueObject<{{declaredValueType}}, {{structName}}>,
156-
IParsableValueObject<{{structName}}>,
160+
"""
161+
);
162+
163+
if (declaredValueType != "string")
164+
source.AppendLine($$"""
165+
IParsableValueObject<{{structName}}>,
166+
"""
167+
);
168+
169+
source.AppendLine($$"""
157170
IValueObject<{{declaredValueType}}, {{structName}}>,
158171
IComparable<{{structName}}>,
159172
IComparable
@@ -216,52 +229,55 @@ namespace {structNamespace};
216229
"""
217230
);
218231

219-
source.AppendLine($$"""
220-
/// <inheritdoc />
221-
public static {{structName}} Parse(string s)
222-
{
223-
var result = TryParse(s);
224-
if (result.IsSuccess(out var identifier, out var error))
225-
return identifier;
226-
227-
throw new ValueObjectException(error.Message);
228-
}
232+
if (declaredValueType != "string")
233+
{
234+
source.AppendLine($$"""
235+
/// <inheritdoc />
236+
public static {{structName}} Parse(string s)
237+
{
238+
var result = TryParse(s);
239+
if (result.IsSuccess(out var identifier, out var error))
240+
return identifier;
241+
242+
throw new ValueObjectException(error.Message);
243+
}
229244
230-
"""
231-
);
245+
"""
246+
);
232247

233-
source.AppendLine($$"""
234-
/// <inheritdoc />
235-
public static Result<{{structName}}> TryParse(string s)
236-
{
237-
if ({{declaredValueType}}.TryParse(s, out var value))
238-
return TryCreate(value);
239-
240-
return Result.Fail<{{structName}}>("The string is not a valid identifier.");
241-
}
248+
source.AppendLine($$"""
249+
/// <inheritdoc />
250+
public static Result<{{structName}}> TryParse(string s)
251+
{
252+
if ({{declaredValueType}}.TryParse(s, out var value))
253+
return TryCreate(value);
254+
255+
return Result.Fail<{{structName}}>("The string is not a valid identifier.");
256+
}
242257
243-
"""
244-
);
258+
"""
259+
);
245260

246-
source.AppendLine($$"""
247-
/// <inheritdoc />
248-
public static bool TryParse(string s, out {{structName}} identifier)
249-
{
250-
return TryParse(s).IsSuccess(out identifier);
251-
}
261+
source.AppendLine($$"""
262+
/// <inheritdoc />
263+
public static bool TryParse(string s, out {{structName}} identifier)
264+
{
265+
return TryParse(s).IsSuccess(out identifier);
266+
}
252267
253-
"""
254-
);
268+
"""
269+
);
255270

256-
source.AppendLine($$"""
257-
/// <inheritdoc />
258-
public static bool TryParse(string s, IFormatProvider provider, out {{structName}} identifier)
259-
{
260-
return TryParse(s).IsSuccess(out identifier);
261-
}
271+
source.AppendLine($$"""
272+
/// <inheritdoc />
273+
public static bool TryParse(string s, IFormatProvider provider, out {{structName}} identifier)
274+
{
275+
return TryParse(s).IsSuccess(out identifier);
276+
}
262277
263-
"""
264-
);
278+
"""
279+
);
280+
}
265281

266282
source.AppendLine($$"""
267283
/// <inheritdoc />
@@ -283,7 +299,7 @@ public override bool Equals(object? obj)
283299
"""
284300
);
285301

286-
if (declaredValueType == "Guid")
302+
if (declaredValueType is "long" or "Guid" or "string")
287303
source.AppendLine("""
288304
/// <inheritdoc />
289305
public override int GetHashCode()
@@ -403,16 +419,17 @@ public int CompareTo(object? obj)
403419
"""
404420
);
405421

406-
source.AppendLine($$"""
407-
/// <summary>Gets the underlying value of the <see cref="{{structName}}" />.</summary>
408-
/// <returns>The underlying value of the <see cref="{{structName}}" />.</returns>
409-
public {{declaredValueType}} To{{fullValueType}}()
410-
{
411-
return _value;
412-
}
422+
if (declaredValueType != "string")
423+
source.AppendLine($$"""
424+
/// <summary>Gets the underlying value of the <see cref="{{structName}}" />.</summary>
425+
/// <returns>The underlying value of the <see cref="{{structName}}" />.</returns>
426+
public {{declaredValueType}} To{{fullValueType}}()
427+
{
428+
return _value;
429+
}
413430
414-
"""
415-
);
431+
"""
432+
);
416433

417434
if (declaredValueType == "Guid")
418435
source.AppendLine("""
@@ -422,6 +439,16 @@ public override string ToString()
422439
return _value.ToString();
423440
}
424441
442+
"""
443+
);
444+
else if (declaredValueType == "string")
445+
source.AppendLine("""
446+
/// <inheritdoc />
447+
public override string ToString()
448+
{
449+
return _value;
450+
}
451+
425452
"""
426453
);
427454
else
@@ -439,6 +466,17 @@ public override string ToString()
439466
source.AppendLine($$"""
440467
private static Result Validate({{declaredValueType}} value)
441468
{
469+
return Result.Ok();
470+
}
471+
"""
472+
);
473+
else if (declaredValueType == "string")
474+
source.AppendLine($$"""
475+
private static Result Validate({{declaredValueType}} value)
476+
{
477+
if (string.IsNullOrWhiteSpace(value))
478+
return Result.Fail("The value must not be empty.");
479+
442480
return Result.Ok();
443481
}
444482
"""
@@ -491,15 +529,27 @@ public override void Write(Utf8JsonWriter writer, {{structName}} identifier, Jso
491529

492530
if (declaredValueType == "Guid")
493531
source.AppendLine(""" writer.WriteStringValue(value.ToString());""");
532+
else if (declaredValueType == "string")
533+
source.AppendLine(""" writer.WriteStringValue(value);""");
494534
else
495535
source.AppendLine(""" writer.WriteNumberValue(value);""");
496536

537+
source.AppendLine($$"""
538+
}
539+
540+
public override {{structName}} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
541+
{
542+
var value = reader.Get{{fullValueType}}();
543+
"""
544+
);
545+
if (declaredValueType == "string")
546+
source.AppendLine("""
547+
if (string.IsNullOrWhiteSpace(value))
548+
throw new InvalidOperationException("The value must not be empty.");
549+
550+
"""
551+
);
497552
source.Append($$"""
498-
}
499-
500-
public override {{structName}} Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
501-
{
502-
var value = reader.Get{{fullValueType}}();
503553
return {{structName}}.Create(value);
504554
}
505555
}

Diff for: src/LightResults.Extensions.GeneratedIdentifier/LightResults.Extensions.GeneratedIdentifier.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<!-- Output -->
3737
<PropertyGroup>
3838
<AssemblyName>LightResults.Extensions.GeneratedIdentifier</AssemblyName>
39-
<Version>9.0.0-preview.3</Version>
39+
<Version>9.0.0-preview.4</Version>
4040
<AssemblyVersion>9.0.0.0</AssemblyVersion>
4141
<FileVersion>9.0.0.0</FileVersion>
4242
<NeutralLanguage>en-US</NeutralLanguage>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace LightResults.Extensions.GeneratedIdentifier.Fixtures.Identifiers;
2+
3+
[GeneratedIdentifier<long>]
4+
public partial struct TestLongId;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace LightResults.Extensions.GeneratedIdentifier.Fixtures.Identifiers;
2+
3+
[GeneratedIdentifier<string>]
4+
public partial struct TestStringId;

Diff for: tests/LightResults.Extensions.GeneratedIdentifier.Fixtures/LightResults.Extensions.GeneratedIdentifier.Fixtures.csproj

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk.Web">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
@@ -10,6 +10,7 @@
1010
<AnalysisLevel>latest-Default</AnalysisLevel>
1111
<IsPackable>false</IsPackable>
1212
<IsTestProject>false</IsTestProject>
13+
<OutputType>Library</OutputType>
1314
</PropertyGroup>
1415

1516
<ItemGroup>

Diff for: tests/LightResults.Extensions.GeneratedIdentifier.Fixtures/Program.cs

-8
This file was deleted.

0 commit comments

Comments
 (0)