You can then C# doc it to explain what the status means.
E.g. like this:
/// <summary>
/// An enum containing the DSN (delivery status notification) action field values, as per <em>RFC 3464</em>.
/// </summary>
/// <remarks><see href="https://www.rfc-editor.org/rfc/rfc3464#section-2.3.3"/></remarks>
public enum DsnAction
{
/// <summary>
/// "indicates that the message could not be delivered to the
/// recipient. The Reporting MTA has abandoned any attempts
/// to deliver the message to this recipient. No further
/// notifications should be expected."
/// </summary>
Failed,
/// <summary>
/// "indicates that the Reporting MTA has so far been unable
/// to deliver or relay the message, but it will continue to
/// attempt to do so. Additional notification messages may
/// be issued as the message is further delayed or
/// successfully delivered, or if delivery attempts are later
/// abandoned."
/// </summary>
Delayed,
/// <summary>
/// "indicates that the message was successfully delivered to
/// the recipient address specified by the sender, which
/// includes "delivery" to a mailing list exploder. It does
/// not indicate that the message has been read. This is a
/// terminal state and no further DSN for this recipient
/// should be expected."
/// </summary>
Delivered,
/// <summary>
/// "indicates that the message has been relayed or gatewayed
/// into an environment that does not accept responsibility
/// for generating DSNs upon successful delivery. This
/// action-value SHOULD NOT be used unless the sender has
/// requested notification of successful delivery for this
/// recipient."
/// </summary>
Relayed,
/// <summary>
/// "indicates that the message has been successfully
/// delivered to the recipient address as specified by the
/// sender, and forwarded by the Reporting-MTA beyond that
/// destination to multiple additional recipient addresses.
/// An action-value of "expanded" differs from "delivered" in
/// that "expanded" is not a terminal state. Further
/// "failed" and/or "delayed" notifications may be provided."
/// </summary>
Expanded,
}
Care must just be taken to parse it case-insensitively, as the RFC says:
The action-value may be spelled in any combination of upper and lower
case characters.
Parsing could e.g. be done in a class like this:
public class DsnActionLookup
{
private readonly Dictionary<string, DsnAction> actions = new(StringComparer.OrdinalIgnoreCase)
{
{ "failed", DsnAction.Failed },
{ "delayed", DsnAction.Delayed },
{ "delivered", DsnAction.Delivered },
{ "relayed", DsnAction.Relayed },
{ "expanded", DsnAction.Expanded }
};
/// <summary>
/// Tries to get the <see cref="DsnAction"/> corresponding to the given action string.
/// </summary>
/// <param name="action">The action string to compare.</param>
/// <param name="dsnAction">The resulting <see cref="DsnAction"/> if found.</param>
/// <returns><c>true</c> if the action string matched; otherwise, <c>false</c>.</returns>
public bool TryGetDsnAction(string action, out DsnAction dsnAction)
{
return actions.TryGetValue(action, out dsnAction);
}
/// <summary>
/// Indexer to retrieve the <see cref="DsnAction"/> corresponding to the given action string.
/// </summary>
/// <param name="action">The action string to compare.</param>
/// <exception cref="KeyNotFoundException">Thrown when the action string does not exist in the lookup.</exception>
/// <returns>The <see cref="DsnAction"/> corresponding to the provided action string.</returns>
public DsnAction this[string action] => actions[action];
}
The
Action
currently is a string. For a programmer, an enum would maybe be more helpful.https://www.rfc-editor.org/rfc/rfc3464#section-2.3.3 defines the values of it. As this s an exclusive (aka terminal) list, it cannot contain more/other entries and it must be contained in a DSN.
So AFAIK it should be safe to parse in an enum?
You can then C# doc it to explain what the status means.
E.g. like this:
Care must just be taken to parse it case-insensitively, as the RFC says:
Parsing could e.g. be done in a class like this: