< Summary

Class:Towel.TagAttributeExtensions
Assembly:Towel
File(s):File 1: /home/runner/work/Towel/Towel/Sources/Towel/TagAttribute.cs
Covered lines:28
Uncovered lines:0
Coverable lines:28
Total lines:84
Line coverage:100% (28 of 28)
Covered branches:12
Total branches:16
Branch coverage:75% (12 of 16)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
File 1: GetTag(...)50%2100%
File 1: GetTag(...)50%2100%
File 1: GetTag(...)50%2100%
File 1: Find(...)90%10100%

File(s)

/home/runner/work/Towel/Towel/Sources/Towel/TagAttribute.cs

#LineLine coverage
 1using System.Reflection;
 2
 3namespace Towel;
 4
 5/// <summary>A value-based "tag" attribute.</summary>
 6[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
 7public class TagAttribute : Attribute
 8{
 9  internal object? Tag;
 10  internal object? Value;
 11
 12  /// <summary>Creates a new value-based "tag" attribute.</summary>
 13  /// <param name="tag">The tag.</param>
 14  /// <param name="value">The value.</param>
 15  public TagAttribute(object? tag, object? value)
 16  {
 17    Tag = tag;
 18    Value = value;
 19  }
 20}
 21
 22/// <summary>Extension methods for reflection types and <see cref="TagAttribute"/>.</summary>
 23public static class TagAttributeExtensions
 24{
 25  /// <summary>Gets a <see cref="TagAttribute"/> on a <see cref="MemberInfo"/>.</summary>
 26  /// <param name="memberInfo">The type to get the <see cref="TagAttribute"/> of.</param>
 27  /// <param name="tag">The tag to get the value of.</param>
 28  /// <returns>
 29  /// - <see cref="bool"/> Found: True if the tag was found; False if not or if multiple tags were found (ambiguous).<br
 30  /// - <see cref="object"/> Value: The value if found or default if not.
 31  /// </returns>
 32  public static (bool Found, object? Value) GetTag(this MemberInfo memberInfo, object? tag)
 4633  {
 4634    if (memberInfo is null) throw new ArgumentNullException(nameof(memberInfo));
 4635    return Find(memberInfo.GetCustomAttributes<TagAttribute>(), tag);
 4636  }
 37
 38  /// <summary>Gets a <see cref="TagAttribute"/> on a <see cref="ParameterInfo"/>.</summary>
 39  /// <param name="parameterInfo">The type to get the <see cref="TagAttribute"/> of.</param>
 40  /// <param name="tag">The tag to get the value of.</param>
 41  /// <returns>
 42  /// - <see cref="bool"/> Found: True if the tag was found; False if not or if multiple tags were found (ambiguous).<br
 43  /// - <see cref="object"/> Value: The value if found or default if not.
 44  /// </returns>
 45  public static (bool Found, object? Value) GetTag(this ParameterInfo parameterInfo, object? tag)
 446  {
 447    if (parameterInfo is null) throw new ArgumentNullException(nameof(parameterInfo));
 448    return Find(parameterInfo.GetCustomAttributes<TagAttribute>(), tag);
 449  }
 50
 51  /// <summary>Gets a <see cref="TagAttribute"/> on a <see cref="MemberInfo"/>.</summary>
 52  /// <typeparam name="TEnum">The type of enum to get the atributes on its fields.</typeparam>
 53  /// <param name="enumValue">The type of enum field to get the <see cref="TagAttribute"/> of.</param>
 54  /// <param name="tag">The tag to get the value of.</param>
 55  /// <returns>
 56  /// - <see cref="bool"/> Found: True if the tag was found; False if not or if multiple tags were found (ambiguous).<br
 57  /// - <see cref="object"/> Value: The value if found or default if not.
 58  /// </returns>
 59  public static (bool Found, object? Value) GetTag<TEnum>(this TEnum enumValue, object? tag)
 60    where TEnum : Enum
 661  {
 662    if (enumValue is null) throw new ArgumentNullException(nameof(enumValue));
 663    return Find(enumValue.GetEnumAttributes<TagAttribute>(), tag);
 664  }
 65
 66  internal static (bool Found, object? Value) Find(System.Collections.Generic.IEnumerable<TagAttribute> enumerable, obje
 5667  {
 5668    bool found = false;
 5669    object? value = default;
 29170    foreach (TagAttribute valueAttribute in enumerable)
 6371    {
 6372      if (ReferenceEquals(tag, valueAttribute.Tag) || (tag is not null && tag.Equals(valueAttribute.Tag)))
 3373      {
 3374        if (found)
 375        {
 376          return (false, default);
 77        }
 3078        found = true;
 3079        value = valueAttribute.Value;
 3080      }
 6081    }
 5382    return (found, value);
 5683  }
 84}