-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add legacy TypeConverter support from System.ComponentModel
This shouldn't be needed in newer ASP.NET Core since the IParsable<T>/IFormattable is the only requirement nowadays. But might be useful in other scenarios.
- Loading branch information
Showing
4 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// <auto-generated/> | ||
#nullable enable | ||
|
||
using System; | ||
using System.ComponentModel; | ||
using System.Globalization; | ||
using StructId; | ||
|
||
[TStructId] | ||
[TypeConverter(typeof(TSelf.StringConverter))] | ||
file readonly partial record struct TSelf(string Value) | ||
{ | ||
partial class StringConverter : TypeConverter | ||
{ | ||
/// <inheritdoc /> | ||
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) | ||
=> sourceType == typeof(string) || sourceType == typeof(TSelf); | ||
|
||
/// <inheritdoc /> | ||
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) | ||
{ | ||
if (value == null) | ||
return default(TSelf); | ||
|
||
if (value is string typedValue) | ||
return TSelf.New(typedValue); | ||
|
||
throw new ArgumentException($"Cannot convert '{value}' to {nameof(TSelf)}", nameof(value)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) | ||
=> destinationType == typeof(string) || destinationType == typeof(TSelf); | ||
|
||
/// <inheritdoc /> | ||
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) | ||
{ | ||
if (value != null) | ||
{ | ||
if (destinationType == typeof(string)) | ||
return ((TSelf)value).Value; | ||
|
||
if (destinationType == typeof(TSelf)) | ||
return value; | ||
} | ||
|
||
throw new InvalidOperationException($"Cannot convert '{value}' to '{destinationType}'"); | ||
} | ||
} | ||
} | ||
|
||
file partial record struct TSelf : INewable<TSelf, string> | ||
{ | ||
public static TSelf New(string value) => throw new NotImplementedException(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// <auto-generated/> | ||
#nullable enable | ||
|
||
using System; | ||
using System.ComponentModel; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Globalization; | ||
using StructId; | ||
|
||
[TStructId] | ||
[TypeConverter(typeof(TSelf.StringConverter))] | ||
file readonly partial record struct TSelf(/*!string*/ TValue Value) | ||
{ | ||
partial class StringConverter : TypeConverter | ||
{ | ||
/// <inheritdoc /> | ||
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) | ||
=> sourceType == typeof(string) || sourceType == typeof(TSelf); | ||
|
||
/// <inheritdoc /> | ||
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) | ||
{ | ||
if (value == null) | ||
return default(TSelf); | ||
|
||
if (value is string typedValue) | ||
return TSelf.New(TValue.Parse(typedValue, culture)); | ||
|
||
throw new ArgumentException($"Cannot convert '{value}' to {nameof(TSelf)}", nameof(value)); | ||
} | ||
|
||
/// <inheritdoc /> | ||
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) | ||
=> destinationType == typeof(string) || destinationType == typeof(TSelf); | ||
|
||
/// <inheritdoc /> | ||
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) | ||
{ | ||
if (value != null) | ||
{ | ||
if (destinationType == typeof(string)) | ||
return ((TSelf)value).Value.ToString(null, culture); | ||
|
||
if (destinationType == typeof(TSelf)) | ||
return value; | ||
} | ||
|
||
throw new InvalidOperationException($"Cannot convert '{value}' to '{destinationType}'"); | ||
} | ||
} | ||
} | ||
|
||
file partial record struct TSelf : INewable<TSelf, TValue> | ||
{ | ||
public static TSelf New(TValue value) => throw new NotImplementedException(); | ||
} | ||
|
||
// This will be removed when applying the template to each user-defined struct id. | ||
file struct TValue : IParsable<TValue>, IFormattable | ||
{ | ||
public static TValue Parse(string s, IFormatProvider? provider) => throw new NotImplementedException(); | ||
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out TValue result) => throw new NotImplementedException(); | ||
public string ToString(string? format, IFormatProvider? formatProvider) => throw new NotImplementedException(); | ||
} |