Skip to content

Commit

Permalink
Add MailAddressConverter and MailAddressCollectionConverter
Browse files Browse the repository at this point in the history
  • Loading branch information
rdeago committed Oct 28, 2023
1 parent c6def14 commit 0cda0ef
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Class `Louis.ComponentModel.SimpleStringConverter<T>` provides a base class for type converters that can convert a specific type to and/or from a string.
This abstract class takes care of boilerplate code and dealing with `object`s; subclasses only have to implement conversions between `string`s and strongly-typed instances.
- Static method `Louis.ComponentModel.SimpleStringConverter.AddToTypeDescriptor<T, TConverter>` creates an instance of [`TyepConverterAttribute`](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.typeconverterattribute) referencing a subclass of `SimpleStringConverter<T>` and registers it for use by [`TypeDescriptor.GetAttributes`](https://learn.microsoft.com/en-us/dotnet/api/system.componentmodel.typedescriptor.getattributes). This enables a converter to be recognized by e.g. [`ConfigurationBinder`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationbinder) with just one line of clean, easy-to-understand code.
- Classes `Louis.ComponentModel.MailAddressConverter` and `Louis.ComponentModel.MailAddressCollectionConverter` perform conversion of [`MailAddress`](https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.mailaddress) and [`MailAddressCollection`](https://learn.microsoft.com/en-us/dotnet/api/system.net.mail.mailaddresscollection), respectively, to and from `string`. They are also good examples of how to subclass `SimpleStringConverter<T>`.

### Changes to existing features

Expand Down
42 changes: 42 additions & 0 deletions src/Louis/ComponentModel/MailAddressCollectionConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Tenacom and contributors. Licensed under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using System.ComponentModel;
using System.Globalization;
using System.Net.Mail;
using CommunityToolkit.Diagnostics;

namespace Louis.ComponentModel;

/// <summary>
/// Provides a type converter to convert <see cref="MailAddressCollection"/> instances to and from strings.
/// </summary>
public sealed class MailAddressCollectionConverter : SimpleStringConverter<MailAddressCollection>
{
/// <summary>
/// Initializes a new instance of the <see cref="MailAddressCollectionConverter"/> class.
/// </summary>
public MailAddressCollectionConverter()
: base(DoConvertFromString, DoConvertToString)
{
}

private static MailAddressCollection DoConvertFromString(ITypeDescriptorContext? context, CultureInfo? culture, string value)
{
Guard.IsNotEmpty(value, nameof(value));
var result = new MailAddressCollection();
try
{
result.Add(value);
}
catch (FormatException e)
{
ThrowHelper.ThrowArgumentException(nameof(value), "Value should be a valid e-mail address, or valid e-mail addresses separated by commas.", e);
}

return result;
}

private static string DoConvertToString(ITypeDescriptorContext? context, CultureInfo? culture, MailAddressCollection value) => value.ToString();
}
47 changes: 47 additions & 0 deletions src/Louis/ComponentModel/MailAddressConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) Tenacom and contributors. Licensed under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Net.Mail;
using CommunityToolkit.Diagnostics;

namespace Louis.ComponentModel;

/// <summary>
/// Provides a type converter to convert <see cref="MailAddress"/> instances to and from strings.
/// </summary>
public sealed class MailAddressConverter : SimpleStringConverter<MailAddress>
{
/// <summary>
/// Initializes a new instance of the <see cref="MailAddressConverter"/> class.
/// </summary>
public MailAddressConverter()
: base(DoConvertFromString, DoConvertToString)
{
}

private static MailAddress DoConvertFromString(ITypeDescriptorContext? context, CultureInfo? culture, string value)
{
#if NET5_0_OR_GREATER
return MailAddress.TryCreate(value, out var result) ? result : ThrowOnInvalidString(nameof(value));
#else
try
{
return new MailAddress(value);
}
catch (FormatException ex)
{
return ThrowOnInvalidString(nameof(value), ex);
}
#endif

[DoesNotReturn]
static MailAddress ThrowOnInvalidString(string parameterName, Exception? innerException = null)
=> ThrowHelper.ThrowArgumentException<MailAddress>(parameterName, "Value should be a valid e-mail address.", innerException);
}

private static string DoConvertToString(ITypeDescriptorContext? context, CultureInfo? culture, MailAddress value) => value.ToString();
}
4 changes: 4 additions & 0 deletions src/Louis/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#nullable enable
Louis.ComponentModel.MailAddressCollectionConverter
Louis.ComponentModel.MailAddressCollectionConverter.MailAddressCollectionConverter() -> void
Louis.ComponentModel.MailAddressConverter
Louis.ComponentModel.MailAddressConverter.MailAddressConverter() -> void
Louis.ComponentModel.SimpleStringConverter
Louis.ComponentModel.SimpleStringConverter<T>
Louis.ComponentModel.SimpleStringConverter<T>.SimpleStringConverter(System.Func<System.ComponentModel.ITypeDescriptorContext?, System.Globalization.CultureInfo?, string!, T>? convertFromString, System.Func<System.ComponentModel.ITypeDescriptorContext?, System.Globalization.CultureInfo?, T, string!>? convertToString) -> void
Expand Down

0 comments on commit 0cda0ef

Please sign in to comment.